home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1191 / 1191.xpi / chrome / reminderfox.jar / content / reminderfox / mail / rmFxIcalMail.js < prev    next >
Text File  |  2009-12-02  |  82KB  |  2,116 lines

  1. /**        
  2.  * rmFxIcalMail.js
  3.  * 
  4. <p>        SEND:    
  5. <ul>        Reminderfox events stored in the users list can be send using the TB/mail facility.
  6. <br>        Sending modes are:
  7. <br>        - just send one or more events from the list to another
  8.                   user, this is the METHOD:PUBLISH. 
  9. <br>        - send one event as "Invitation" or "Schedule", this is 
  10.                   based on RFC2446 (iTIP)
  11. <p>            Current implementation supports: 
  12. <br>          -- METHOD: PUBLISH, REQUEST, REPLY
  13. </ul> 
  14.         RECEIVE:    
  15. <ul>        ICS-file with RFC2445 (iCalendar) data is read and added
  16.             to the Reminderfox.ics file.
  17. <br>        The ICS-data can be part of the body or attached as an ICS file.
  18. <br>        The data is interpreted in conformance to RFC2446 and supports:
  19. <br>         -- METHOD: PUBLISH, REQUEST, REPLY, CANCEL
  20. </ul>
  21.         NOTE:    
  22. <br>        Both RFC's are not covered in all aspects, for actual implementation
  23.              please refer to  'RmFx_iCal_iTIP_Implementation.pdf'
  24.  
  25. <p>        @since
  26.          2008-04-14    
  27. <ul>         - messageID added to event. This enables to call msg from reminder
  28.                    and reminder from msg;
  29. <br>         - msg tagging with iCal METHOD;
  30. <br>         - D&D added;
  31. <br>         - Attendee can process CANCEL send by Organizer;
  32. <br>         - supports rmFxUtil.PromptAlert(msg) instead of plain 'alert';
  33. <br>
  34.         2009-03 D&D:  moved to  'utils/rmFxDragDrop.js'
  35. </ul>
  36. *     @see             'RmFx_iCal_iTIP_Implementation.pdf'
  37. */
  38.  
  39. var rmFx_fromMailadr;
  40. var rmFx_iCalMETHOD;  
  41. var rmFx_iCalAttendees;
  42. var rmFx_iCalOrganizer;
  43. var rmFxMessageId;
  44. var rmFxIcalLastEvent;
  45.  
  46.  
  47. /**
  48.  *     Processes message for iCal-content 
  49. <P>         1. reads data from 'msgHdr'
  50. <br>         2. reads mail ICS-data from 
  51. <br>            (a.)  mail-inline (body)   
  52. <br>            (b.)  first attachment including a iCal data set
  53. <br>    If iCal found, passes to add the event, if no iCal will add a reminder
  54.         for the message to the event list
  55.         
  56. <P>        @return    rv    true: if iCal/ICS data found
  57.  */
  58. function rmFxGetiCalMailed() {
  59.     var rv = false;
  60.     var ret = "\n"; 
  61.     
  62.     // --- get some msgHeader Infos ------    
  63.     var msgHdr = gDBView.hdrForFirstSelectedMessage;
  64.     // subject
  65.     var rmFxSummary = msgHdr.mime2DecodedSubject;
  66.     // from
  67.     var rmFxFrom =  msgHdr.mime2DecodedAuthor;
  68.     rmFx_fromMailadr =rmFxFrom;                // need for processing eg REPLY
  69.     
  70.     // recipients
  71.     var rmFxTo = msgHdr.mime2DecodedRecipients;
  72.     
  73.     // messageID
  74.     rmFxMessageId = "<" + msgHdr.messageId.replace(new RegExp(/\"/g),"") + ">";
  75.     // date   
  76.     var dateStr =  msgHdr.date;
  77.     var time = new Date();
  78.     time.setTime(dateStr / 1000);        
  79.    
  80.     var timeString = reminderFox_mail_getTimeString( time );
  81.     var dateVariableString;
  82.     try {
  83.         dateVariableString = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + 
  84.                 "." + REMINDER_FOX_LIST_DATE_LABEL);
  85.     } catch(e) {}
  86.          
  87.     var rmFxDate =reminderFox_getDateVariable( null, time, dateVariableString ) 
  88.             + "  " + timeString;
  89.  
  90.     var mInvitation = "     " +reminderFox_getBundle().getString("rf.add.mail.message.date") + ": " + rmFxDate + ret
  91.                     + "     " +reminderFox_getBundle().getString("rf.add.mail.message.sender") + ": " + rmFxFrom + ret
  92.                     + "     " +reminderFox_getBundle().getString("rf.add.mail.message.recipients") + ": " + rmFxTo + ret    ;
  93.  
  94.     var _baseURI= this.content.document.body.baseURI;
  95.     var _content= this.content.document.body.textContent;
  96.     var _contentType= this.content.document.contentType;
  97.     var _documentURI= this.content.document.documentURI;
  98.     var _title= this.content.document.title;
  99.  
  100.     // 1a.   check if events in the body, pass to "Add Reminder"
  101.     var rvTxt = rmFxGetiCalFromTextBody(_content, mInvitation);
  102.     
  103.     if (rvTxt == true) return;   // the event is read from the boday, so done!
  104.     
  105.     //2.    check Attachments for events, pass to "Add Reminder"
  106.  
  107.     if (currentAttachments.length > 0) {
  108.         var i=0;
  109.         while (i < currentAttachments.length) {    
  110.             var xx = currentAttachments[i].contentType.toLowerCase();    
  111.             if (  (xx == "text/calendar")                     /* 'normal apps */                    
  112.                 || (xx == "application/ics")                 /* Google Calendar */     
  113.                 || (xx == "application/octet-stream")) {     /* some calendars do not identify as calendar type */         
  114.                 var _contentType =    xx;
  115.                 var _url =    currentAttachments[i].url;
  116.                 var _name =    "iCalMsgAttReceive" + i + ".txt";
  117.                 var _uri =    currentAttachments[i].uri; 
  118.     
  119.                 var temp = Components.classes["@mozilla.org/file/directory_service;1"]
  120.                              .getService(Components.interfaces.nsIProperties)
  121.                              .get("TmpD", Components.interfaces.nsIFile);
  122.                 
  123.                 var attfile = messenger.saveAttachmentToFolder(
  124.                     _contentType, _url, _name, _uri, temp, null); 
  125.                     
  126.                 // delete the temporary file  automatically on exit            <<< //gW_PB for Postbox         
  127.                 externalAppLauncher.deleteTemporaryFileOnExit(attfile);
  128.                                 
  129.                 //  we need  Timeout ---> +++2do  use eventhandler instead!!
  130.                 setTimeout(rmFxGetiCalFromAttachment,500, mInvitation, attfile, _content, rmFxMessageId);    
  131.         //        rmFxGetiCalFromAttachment(mInvitation, attfile, _content, rmFxMessageId);    
  132.         
  133.             rv = true;
  134.             }
  135.             i++;
  136.         }        
  137.     }
  138.  
  139.     //  3. coming to here  with rv=false, probably the msg was D&D from mail:3pane
  140.     //   +++2do check  +++2do check  +++2do check  +++2do check  +++2do check  +++2do check  +++2do check  +++2do check   
  141.     if (rv == false) {        
  142.         reminderFox_thunderBirdAddEmailReminder();
  143.     }
  144.     
  145.     rmFxIcalLastEvent = null;
  146.     return rv;                  
  147. }
  148.  
  149. /**
  150.  * Read iCal/ICS data from attachment, if no data found alternativly check the body of the message
  151.  * 
  152.  * @param mInvitation    --> METHOD as with RFC defined
  153.  * @param attfile        --> temp file() of attachment
  154.  * @param content        --> messages body text
  155.  * @param rmFxMessageId    --> the msgHdr.messageId
  156.  * @return
  157.  */
  158. function rmFxGetiCalFromAttachment(mInvitation, attfile, content, rmFxMessageId) { 
  159.     var rv; 
  160.     var reminderFoxEvents = new Array();
  161.     var reminderFoxTodosArray = { };
  162.     reminderFox_readInRemindersAndTodosICSFromFile(reminderFoxEvents, reminderFoxTodosArray, attfile, true);
  163.     
  164.     // check if we've successfully found any reminders or todo events        
  165.     var foundEventsInAttachment = reminderFoxEvents.length != 0;
  166.     if ( !foundEventsInAttachment ) {
  167.         for ( var n in reminderFoxTodosArray ) {
  168.             var importedTodos = reminderFoxTodosArray[n];
  169.             if ( importedTodos.length > 0 ) {
  170.                 foundEventsInAttachment = true;
  171.                 break;
  172.             }
  173.         }
  174.     }
  175.     
  176.     // if so, read-in from the attachment
  177.     if ( foundEventsInAttachment ) {    
  178.         rv = rmFxGetiCalEvents( mInvitation, reminderFoxEvents, reminderFoxTodosArray);  
  179.     } 
  180.     rmFx_iCalTagging (rv);
  181.     
  182.     return rv;
  183. }
  184.  
  185. function rmFx_iCalTagging (rv) {
  186.     if ((rmFx_iCalMETHOD != "") && (rv == true)){
  187.         rmFx_msgTAGing('iCal-' + rmFx_iCalMETHOD, true, '#3333FF');    
  188.     }
  189. }
  190.  
  191.  
  192. /**
  193.  *     Support FX D&D a URL with ICS download link
  194. <br>         ex:  http://dl.erweiterungen.de/kalenderdateien/Feiertage_2006-2010_DE.ics
  195.  * 
  196.  *     @param    url
  197.  * 
  198.  *  @since     2008-10-30
  199.  *  @todo     just supports only subscription not import from (url)
  200.  */
  201. function rmFxSubscribeOrAddReminder(url) {
  202.         
  203.     // --- ask user to subscribe or add as reminder --- 
  204.     var title =    reminderFox_getBundle().getString('rf.options.subscribe.title');
  205.     var msg =     reminderFox_getBundle().getString('rf.options.subscribe.description1')
  206.                 + '\n' + reminderFox_getBundle().getString('rf.options.subscribe.description2'); 
  207.     var key0 =    reminderFox_getBundle().getString('rf.options.subscribe');    
  208.     var key1 =    reminderFox_getBundle().getString('rf.button.cancel'); 
  209.     var key2 =    reminderFox_getBundle().getString('rf.options.subscribe.add2reminders'); 
  210.   
  211.     switch (rmFxUtil.ConfirmEx(title, msg, key0, key1, key2) ) {
  212.     case 0:    
  213.         reminderFox_subscribeWithReminderFox(url); break;
  214.     case 1:
  215.         alert ("Canceled, see you  ;-)");  
  216.         break;
  217.     case 2:    
  218.             // GetICSfromHTTP(url);                    
  219.         // ++++2do  ++++2do  ++++2do  ++++2do  ++++2do  ++++2do  ++++2do 
  220.         //        needs FX download from url and handle as new reminder 
  221.             alert ("Sorry, coming soon ;-)");
  222.         // ++++2do  ++++2do  ++++2do  ++++2do  ++++2do  ++++2do  ++++2do 
  223.         break;
  224.     }
  225. }
  226.  
  227. function rmFxGetiCalFromTextBody(_content, mInvitation) {    
  228.     var reminderFoxEvents = new Array();
  229.     var reminderFoxTodosArray = { };
  230.     
  231.     reminderFox_readInRemindersAndTodosICSFromString(reminderFoxEvents, reminderFoxTodosArray, _content, true);
  232.  
  233.     var rv = rmFxGetiCalEvents(mInvitation,  reminderFoxEvents, reminderFoxTodosArray);
  234.     return rv;
  235. }
  236.  
  237. function rmFxGetiCalEvents( mInvitation, reminderFoxEvents, reminderFoxTodosArray) {
  238.     //  here we need to know the METHOD of the event
  239.     //        with "send"     it's set by processing before
  240.     //        with "receive"    it's written to "this.reminderfox_Method"
  241.     rmFx_iCalMETHOD = this.reminderfox_Method; 
  242.  
  243.     // now iterate over each event and do special processing
  244.     // get infos into reminder.notes ... depended of "METHOD"    
  245.     for ( var i = 0; i < reminderFoxEvents.length; i++ ) {
  246.         var reminder = reminderFoxEvents[i];    
  247.         var result = reminderFox_processExtraScheduleInfo(reminder, mInvitation, rmFx_iCalMETHOD );
  248.         if (result != "") {
  249.             rmFxUtil.PromptAlert(result);
  250.             return false;
  251.         }
  252.     }        
  253.  
  254.     // #1   handle multiple VEVENT OR  VTODO -->>  import them all with normal import
  255.      for ( var list in reminderFoxTodosArray ) {
  256.          var cList = reminderFoxTodosArray[list];
  257.      }
  258.  
  259.     if ((reminderFoxEvents.length >1) || (!!cList)) {  
  260.          
  261.        // prompt the user to import     
  262.         var title =    reminderFox_getBundle().getString("rf.mail.ical.import.overwrite.title");
  263.         var msg =    reminderFox_getBundle().getString("rf.mail.ical.import.overwrite.description");
  264.         var key0 =    reminderFox_getBundle().getString("rf.button.ok");
  265.         var key1 =    reminderFox_getBundle().getString("rf.button.cancel"); 
  266.             
  267.         if (rmFxUtil.ConfirmEx(title, msg, key0, key1) == 1 ) {  // cancel pressed
  268.                 return false;
  269.         }    
  270.         
  271.         // add 'Category' items to every event
  272.         for (var i = 0; i < reminderFoxEvents.length; i++) {
  273.             reminderFoxEvents[i].categories = reminderFoxEvents[i].categories + ",iEvent";
  274.         }            
  275.         reminderFox_addMultipleEvents(reminderFoxEvents, reminderFoxTodosArray);
  276.         
  277.         return true;
  278.     }     
  279.     
  280.     // #2a  single Event/Schedule.
  281.     //         Check for Reminders passed. None --> return false;
  282.     var reminder = reminderFoxEvents[0];    // the 'read' reminder
  283.     if (reminder == null) return false;        // no Reminders, return
  284.     
  285.     // check if previous event is the same as this one (POSTBOX workaround)
  286.     try {
  287.         if ((reminder.id == rmFxIcalLastEvent.id) 
  288.             && (reminder.extraInfo == rmFxIcalLastEvent.extraInfo)) {
  289.             // rmFxUtil.PromptAlert(" here we have an duplicated event");
  290.             rmFxIcalLastEvent = null;
  291.             return false;
  292.         }
  293.     } catch (ex) {}
  294.     rmFxIcalLastEvent = reminder;
  295.     
  296.     // #2b     loop with all reminders in list and check if already in reminder.ics
  297.     //         known: return false
  298.     //         new:   call the "Add Reminder" dialog, return "true" if finally added, 
  299.     //                 "false" if user suspend adding
  300.     var rmFx_statusMsg="";  
  301.     reminder.messageID = rmFxMessageId;
  302.     
  303.     var newExtra = rmFx_extraInfoArray(reminder);    // the 'extraInfo' items    
  304.     
  305.     var activeReminders = reminderFox_getReminderEvents();
  306.     
  307.     for (var nR =0; nR < activeReminders.length; nR++) {    
  308.         if (reminder.id == activeReminders[nR].id ) { 
  309.             // reminder already known, check for details and alert it.
  310.         
  311.             var oldExtra = rmFx_extraInfoArray(activeReminders[nR]);    
  312.             var same  = (rmFx_extraInfo(newExtra,"DTSTAMP")) 
  313.                         == (rmFx_extraInfo(oldExtra,"DTSTAMP"))
  314.                         && (rmFx_extraInfo(newExtra,"SEQUENCE")) 
  315.                         == (rmFx_extraInfo(oldExtra,"SEQUENCE"))    ;        //++++2do  ++++2do  ++++2do  ++++2do  ++++2do  
  316.                                                                         //  check for oldSEQ > newSEQ  ==> ERR
  317.             var older = (rmFx_extraInfo(newExtra,"DTSTAMP")) 
  318.                         <= (rmFx_extraInfo(oldExtra,"DTSTAMP"))
  319.                         || (rmFx_extraInfo(newExtra,"SEQUENCE")) 
  320.                          < (rmFx_extraInfo(oldExtra,"SEQUENCE"))    ;        //++++2do  ++++2do  ++++2do  ++++2do  ++++2do  
  321.                                                                     //        for oldDTSTAMP > new ==> ERR
  322.         
  323.             switch (rmFx_iCalMETHOD) {
  324.                 
  325.                 case "CANCEL":  {
  326.                     // check if msg/cancel was already processed 
  327.                     if  (same == true) {
  328.                         rmFx_statusMsg =    "[iCal  CANCEL] " + "  ┬╗" + activeReminders[nR].summary     + "┬½"
  329.                                         +    "\n\n" + mInvitation                     
  330.                                         +    "\n\n" + reminderFox_getBundle().getString("rf.schedule.attendee.processed");                                
  331.                         rmFxUtil.PromptAlert(rmFx_statusMsg);
  332.                         return false;
  333.                     }
  334.                     if  (older == true) {
  335.                         rmFx_statusMsg =    "[iCal  CANCEL] " + "   ┬╗" + activeReminders[nR].summary     + "┬½"
  336.                                         +    "\n\n" + mInvitation                                            
  337.                                         +    "\n\n" + reminderFox_getBundle().getString("rf.schedule.older1.processed")
  338.                                         +    "\n"   + reminderFox_getBundle().getString("rf.schedule.older2.processed")    ;                            
  339.                         rmFxUtil.PromptAlert(rmFx_statusMsg);
  340.                         return false;
  341.                     }
  342.                     // save all event-items {reminder.xx} if not included 
  343.                     // in CANCEL-msg {activeReminders[nR].xx}
  344.                     //     reminder.categories, reminder.location, reminder.url, reminder.priority, 
  345.                     // also set Description to [iCal CANCEL] .... 
  346.                     // 
  347.                     if (reminder.categories == null) {reminder.categories = activeReminders[nR].categories};
  348.                     if (reminder.location == null) {reminder.location = activeReminders[nR].location};
  349.                     if (reminder.url == null) {reminder.url = activeReminders[nR].url};
  350.                     if (reminder.priority == null) {reminder.priority = activeReminders[nR].priority};
  351.                     reminder.notes = reminder.notes +'\n\n' +  activeReminders[nR].notes;
  352.         
  353.                     break;
  354.                 }
  355.                 
  356.                 case "REQUEST":  {                                                    
  357.                     // check if msg/reply was already processed 
  358.                     if  (same == true) {
  359.                         rmFx_statusMsg =  "[iCal  REQUEST] " + "   ┬╗" + activeReminders[nR].summary + "┬½"
  360.                                             + "\n\n" + mInvitation                                                                            
  361.                                             + "\n\n" + reminderFox_getBundle().getString("rf.schedule.attendee.processed");                                
  362.                         rmFxUtil.PromptAlert(rmFx_statusMsg);
  363.                         return false;
  364.                     }
  365.                     if  (older == true) {
  366.                         rmFx_statusMsg =  "[iCal  REQUEST] " + "   ┬╗" + activeReminders[nR].summary     + "┬½"                        
  367.                                     +     "\n\n" + mInvitation
  368.                                     +     "\n\n" + reminderFox_getBundle().getString("rf.schedule.older1.processed")
  369.                                     +     "\n"   + reminderFox_getBundle().getString("rf.schedule.older2.processed")    ;                            
  370.                         rmFxUtil.PromptAlert(rmFx_statusMsg);
  371.                         return false;
  372.                     }                
  373.                     break;
  374.                 }
  375.                 
  376.                 case "REPLY":  {                
  377.                     // check if msg/reply was already processed.
  378.                     // result on 'same' only doesn't say if the current 
  379.                     // processed msg was already processed.
  380.                     // So we check if a TAG 'iCal-Reply' is added to the msg.
  381.     
  382.                     // this.currentHeaderData.tags.headerValue
  383.                     var msgHdr = gDBView.hdrForFirstSelectedMessage;
  384.                     var msgKeys = msgHdr.getStringProperty("keywords");
  385.                     if   ((same == true) && (msgKeys.indexOf("iCal-REPLY") > -1)) {
  386.     
  387.                         var msg =  "[REPLY] " + "   ┬╗" + activeReminders[nR].summary     + "┬½"
  388.                                     + "\n\n" + mInvitation
  389.                                     + "\n\n" + reminderFox_getBundle().getString("rf.schedule.attendee.processed");
  390.                         if (confirm(msg + "\n\n" + reminderFox_getBundle().getString("rf.schedule.processReply")) == false) {
  391.                             return false;
  392.                         }  
  393.                     }
  394.     
  395.                     var attNo;
  396.                     
  397.                     rmFx_fromMailadr = msgHdr.mime2DecodedAuthor;
  398.                     
  399.                     var fromAttendee = rmFx_fromMailadr.substring(
  400.                                 rmFx_fromMailadr.indexOf( "<" ) + 1,
  401.                                 rmFx_fromMailadr.indexOf( ">" ));
  402.                     var fromATT = fromAttendee.toUpperCase();
  403.                     
  404.                     for ( var i = 0; i < rmFx_iCalAttendees.length; i++ ) {                                                                
  405.                         if (rmFx_iCalAttendees[i].toUpperCase().indexOf(fromATT) > -1) attNo=i;
  406.                     }
  407.                       // is the "from" address == the ATTENDEE ??, 
  408.                       // if NOT  --> unknown CU ( + a "Party Crasher") ... 
  409.                     //     So we have to ask the user which ATTENDEE has to be taken here
  410.                     if (rmFx_iCalAttendees[attNo] == null) {
  411.                         
  412.                         var results = { attendees:rmFx_iCalAttendees };
  413.                         window.openDialog("chrome://reminderfox/content/mail/rmFxReplyAttendees.xul",
  414.                         "rmFx-set-getReplyAttendee", "chrome,resizable,modal", results);        
  415.                         // CANCEL and not seleteced ==  -1
  416.                         // OK and selected == #
  417.                         if (results.attendeeNo == -1){
  418.                             return false;}
  419.                         
  420.                         var xx= rmFx_iCalAttendees[results.attendeeNo];
  421.                         
  422.                         var fndIndex = xx.toUpperCase().lastIndexOf( "MAILTO:" ); 
  423.                         if (fndIndex == -1) { return false};
  424.                         var fromATT =  xx.substring( fndIndex + 7).toUpperCase();
  425.                     }
  426.                     // clone the stored event and update some items from
  427.                     // newEvent [REPLY] to oldEvent [the stored]
  428.                     //  - save the .notes
  429.                     var replyReminderNotes = reminder.notes;
  430.     
  431.                     //  - ATTENDEE  grap the new 
  432.                     for ( var i = 0; i < newExtra.length; i++ ) {                                                                
  433.                         if (newExtra[i].toUpperCase().indexOf(fromATT) > -1) var iNew=i;
  434.                     }
  435.                     for ( var i = 0; i < oldExtra.length; i++ ) {                                                                
  436.                         if (oldExtra[i].toUpperCase().indexOf(fromATT) > -1) var iOld=i;
  437.                     }        
  438.                     oldExtra[iOld] = newExtra[iNew];
  439.     
  440.                     // rebuild the extraInfo string
  441.                     for ( var i = 0; i < oldExtra.length; i++ ) {
  442.                         if (i==0) {activeReminders[nR].extraInfo = oldExtra[i];
  443.                         } else {
  444.                         activeReminders[nR].extraInfo += "\\n" + oldExtra[i];}
  445.                     }    
  446.     
  447.                     reminder = activeReminders[nR];
  448.                     reminder.notes = replyReminderNotes
  449.                         + "\n _._._._._._._ " + reminderFox_getBundle().getString("rf.schedule.previous") + " _._._._._._._\n" 
  450.                         + activeReminders[nR].notes;  
  451.                     break;                
  452.                 }    //METHOD:REPLY
  453.                 
  454.                 default: {//METHOD: ... all other (for the moment)                                             
  455.                     //  get info from reminder 'in the list'  
  456.                     
  457.                     var rSEQ = rmFx_extraInfo(oldExtra,'sequence')
  458.                     var rDTSTAMPz = rmFx_extraInfo(oldExtra,'dtstamp');
  459.                    
  460.                     var rDTSTAMP = "";
  461.                     if (rDTSTAMPz != null ) {
  462.                            rDTSTAMP= reminderFox_parseDateTimes(rDTSTAMPz) ;
  463.                     }
  464.                     //  get info from 'new' reminder                       
  465.                     var nSEQ = rmFx_extraInfo(newExtra,'sequence'); 
  466.                     var nDTSTAMPz = rmFx_extraInfo(newExtra,'dtstamp');       
  467.                      
  468.                     var nDTSTAMP = "";
  469.                     if ( nDTSTAMPz != null ) {
  470.                             nDTSTAMP =  reminderFox_parseDateTimes(nDTSTAMPz) ;
  471.                     }  
  472.                     var newStr = reminderFox_getBundle().getString("rf.schedule.new");
  473.                     var oldStr = reminderFox_getBundle().getString("rf.schedule.old");
  474.                     
  475.                     var info1 = reminderFox_getBundle().getString("rf.reminder") + " [ " + activeReminders[nR].summary + " ] \n"
  476.                         +reminderFox_getBundle().getString("rf.schedule.check.summary")+ nR + "\n\n";  
  477.                                                                                                 
  478.                     var info2 =  "\n\nSEQUENCE\n    "+ newStr +":  [#"     + nSEQ      + "]     "+ oldStr +": [#" + rSEQ
  479.                         +   "]\nDTSTAMP \n     "+ newStr +":  [" + nDTSTAMP + "]     "+ oldStr +":  [" + rDTSTAMP + "]";    
  480.                 
  481.                     if ((nSEQ *1) > (rSEQ*1)) { // new SEQUENCE should be greater
  482.                         rmFx_statusMsg = reminderFox_getBundle().getString("rf.schedule.new") + " '" + reminderfox_Method + "' "
  483.                                         + " SEQUENCE" + " #" + nSEQ ;
  484.                 //      alert (info1  + rmFx_statusMsg +  info2) ;                    
  485.                     } else {                                             
  486.                         if (nDTSTAMPz  <= rDTSTAMPz  ) {                    
  487.                             rmFx_statusMsg = 'SEQUENCE / DTSTAMP ' + reminderFox_getBundle().getString("rf.schedule.notValid");    
  488.                             rmFxUtil.PromptAlert(info1  + rmFx_statusMsg +  info2) ;
  489.                             return false;
  490.                             
  491.                         } else {      
  492.                             rmFx_statusMsg = reminderFox_getBundle().getString('rf.schedule.newDate') + '  [' + nDTSTAMP + ']';
  493.                               //              alert (info1  + rmFx_statusMsg +  info2) ;
  494.                         }
  495.                     }                        
  496.     
  497.                     if (rmFx_statusMsg != ""  && activeReminders[nR].notes != null)  {
  498.                         reminder.notes += "\n _._._._._._._ " 
  499.                                             + reminderFox_getBundle().getString("rf.schedule.previous") 
  500.                                               +  " _._._._._._._\n" + 
  501.                         activeReminders[nR].notes   
  502.                     }           
  503.                 } // METHOD  ... all other
  504.             } // switch  
  505.         } // reminder already known    
  506.     } //#2a   -- loop with all reminders in  list 
  507.             
  508.     var rv = reminderFox_addReminderHeadlessly( reminder, true, true );  // gW 2009-02-25 edit flag added
  509.     return rv;  // should be true if added to list, so tag the msg
  510. }
  511.  
  512.  
  513. function reminderFox_processExtraScheduleInfo(reminder, mInvitation, rmFx_Method ) { 
  514. /*     here we prepare the reminder.notes   to reflect special schedule items 
  515.  */ 
  516.      var msgReturn="";
  517.      
  518.     if ( reminder.extraInfo == null ) return msgReturn;
  519.  
  520. //  here we need to know the METHOD of the event
  521. //         it's written to "this.reminderfox_Method"  
  522. //             eg.  REPLY, REQUEST, CANCEL, COUNTER, DECLINECOUNTER
  523.  
  524.     //var rmFx_iCalMETHOD = this.reminderfox_Method;    
  525.             
  526.     var addPerson = "";
  527.     var addOption="";        var iSchComment = null;        var iSchStatus = null;  
  528.     var nDTSTAMP;            var iSchStart;                var iSchEnd;            
  529.     var option ="";
  530.     var ret = "\n";    
  531.     
  532.     var extraInfos =  rmFx_extraInfoArray(reminder);
  533.         
  534.     var nDTSTAMPz = rmFx_extraInfo(extraInfos,"DTSTAMP"); 
  535.     if ( nDTSTAMPz != "" ) {
  536.            nDTSTAMP  =  reminderFox_parseDateTimes(nDTSTAMPz) ;  
  537.     }
  538.     var nSEQ = rmFx_extraInfo(extraInfos,"SEQUENCE"); 
  539.     
  540.     option = rmFx_extraInfo(extraInfos,"COMMENT"); 
  541.     if ( option != "" )
  542.         iSchComment =  option + ret;             
  543.  
  544.     // next items go with  'addOption' to Notes
  545.             function addOptItem (option, optText) {
  546.                 //    var option = rmFx_extraInfo(extraInfos,"PRIORITY"); 
  547.                 return ((option == null) || (option == ""))
  548.                     ? ""
  549.                     : "    " + optText + " [" + option +  "]";
  550.             }
  551.     addOption += addOptItem (rmFx_extraInfo(extraInfos,"PRIORITY"), "Priority");
  552.     addOption += addOptItem (rmFx_extraInfo(extraInfos,"CLASS"), "Class");
  553.     addOption += addOptItem (rmFx_extraInfo(extraInfos,"CUTYPE"), "CuType");
  554.     addOption += addOptItem (rmFx_extraInfo(extraInfos,"TRANSP"), "TRANSP");
  555.  
  556.     // ---->>  process PERSONS infos  ------
  557.         var myMailAccounts = rmFxMsg.myMailIDs();
  558.                  
  559.         rmFx_iCalOrganizer = rmFx_extraInfo(extraInfos,"ORGANIZER", ";");
  560.         
  561.         // check if ORGANIZER is part of my accounts, 
  562.         //    if METHOD:REPLY  it has to be! Else ERROR, don't add to reminder.ics
  563.         if (rmFx_Method == "REPLY") {
  564.             var fndIndex = rmFx_iCalOrganizer.toUpperCase().lastIndexOf( "MAILTO:" ); 
  565.                 if (fndIndex != -1) {
  566.                 var fndString = "<" + rmFx_iCalOrganizer.substring( fndIndex + 7) + ">";
  567.                 if (myMailAccounts.indexOf(fndString) == -1 ) {
  568.                     msgReturn = "[REPLY] " +reminderFox_getBundle().getString("rf.schedule.replyWrongOrganizer")
  569.                         +  ": \n" + fndString;
  570.                     return msgReturn;
  571.                 }
  572.             }
  573.         }  
  574.       
  575.         // get PARTSTAT for myAccount    
  576.         var _Attendees = rmFx_extraInfo(extraInfos,"ATTENDEE", ";", true);  // true==read multiple entries
  577.         var attPart ="";
  578.         
  579.         rmFx_iCalAttendees = _Attendees.split("\n");
  580.         
  581.         if (rmFx_iCalAttendees.length > 0  || nSEQ != null){
  582.             for (var n=0; n<rmFx_iCalAttendees.length; n++){
  583.                 rmFx_iCalAttendees[n] = rmFx_iCalAttendees[n].toUpperCase();
  584.                 var fnd =  rmFx_iCalAttendees[n].lastIndexOf("MAILTO:");                        
  585.                 if (fnd != -1) {
  586.                     var address = rmFx_iCalAttendees[n].substring(fnd+7);
  587.                     if (address.indexOf(myMailAccounts)) {
  588.                             
  589.                         fnd =  rmFx_iCalAttendees[n].indexOf("PARTSTAT=");
  590.                         if (fnd != -1) {
  591.                             var attPart = rmFx_iCalAttendees[n].substring(fnd+9);
  592.                             fnd = attPart.indexOf(";");
  593.                             if (fnd == -1) {attPart.indexOf(":")};
  594.                             var attPart = attPart.substring(0,fnd);    
  595.                         }
  596.                     }
  597.                 }
  598.             }
  599.         }
  600.         var wPART ="";
  601.         if (rmFx_Method != "REQUEST") { var wPART = "  " + attPart; }
  602.         var extraInfoSchedule = "[iCal] " + rmFx_Method + wPART + ": " + reminderFox_getBundle().getString("rf.schedule") ;    
  603.         if ( nDTSTAMP != null && nDTSTAMP.length > 0 ) {
  604.             extraInfoSchedule += " " + reminderFox_getBundle().getString("rf.schedule.asof") + "  " +nDTSTAMP;
  605.         }
  606.         if ( nSEQ != null ) {
  607.             extraInfoSchedule += "    [# " + nSEQ + "]" + ret ;
  608.         }
  609.         extraInfoSchedule += mInvitation + ret;    
  610.  
  611.     // <<<----  process PERSONS infos  ------
  612.  
  613.              
  614.     switch (rmFx_Method) {
  615.         case "REQUEST": 
  616.         case "PUBLISH": {    // this is send to ATTENDEE(s), can be 
  617.                                             // - new 
  618.                                             // - revised 
  619.     
  620.                     // ++++++++++++ Google Calendar Special  ++++++++++++
  621.                      if ( reminder.notes != null && reminder.notes.length > 0 ) {
  622.                         var iGMail = reminder.notes.toLowerCase().indexOf("http://www.google.com/calendar/event?action=view");
  623.                         if ( iGMail != -1) {
  624.                             var iGMail1 = reminder.notes.toLowerCase().indexOf(" ",iGMail);
  625.                             var httpGMail = reminder.notes.substring(iGMail,iGMail1);
  626.                             reminder.url = httpGMail;
  627.                         }
  628.                      }
  629.                     // ++++++++++++ Google Calendar Special  ++++++++++++
  630.              
  631.             if (addOption != "" ) 
  632.                 extraInfoSchedule += reminderFox_getBundle().getString("rf.schedule.options") +
  633.                 " ______________________" + ret + addOption + ret;
  634.  
  635.             if (iSchComment != null )                                     
  636.                 extraInfoSchedule += reminderFox_getBundle().getString("rf.schedule.comment") +                        
  637.                 " ______________________" + ret + iSchComment + ret;
  638.         
  639.              if (reminder.notes != null && reminder.notes.length > 0 ) {
  640.                 reminder.notes = "> " + reminder.notes.replace(new RegExp(/\n/g),"\n>");
  641.              }
  642.              
  643.              if (reminder.notes != null ) {                                
  644.                 extraInfoSchedule +=     reminderFox_getBundle().getString("rf.schedule.description") +                    
  645.                 "  ______________________" + ret                         
  646.                 +  reminder.notes    + ret;
  647.              } 
  648.                            
  649.             // add category signifying that this is an invitation                                    
  650.             var iCalCategory = reminderFox_getBundle().getString("rf.mail.ical.send.subject.invitation"); //   "invitation";  
  651.             var iCalCategoryLC = iCalCategory.toLowerCase(); //   "invitation";  
  652.             if ( reminder.categories != null && reminder.categories.length > 0 ) {
  653.                 if (reminder.categories.toLowerCase().indexOf(iCalCategoryLC) == -1){
  654.                      reminder.categories = reminder.categories + ", " + iCalCategory;}
  655.                 }    else { reminder.categories = iCalCategory;
  656.             }
  657.             reminder.notes = extraInfoSchedule;    
  658.             return msgReturn;
  659.             break;                        
  660.         } //case:REQUEST" & "PUBLISH"
  661.  
  662.         case "REPLY": {    // this is send back to ORGANIZER 
  663.             
  664.             reminder.notes = extraInfoSchedule;    
  665.             return msgReturn;
  666.             break;                    
  667.         }    //case "REPLY"
  668.         
  669.         case "CANCEL": {    // this 'cancel's the local event/invitation
  670.             
  671.             reminder.notes = extraInfoSchedule;    
  672.             return msgReturn;
  673.             break;                    
  674.         }    //case "CANCEL"
  675.         
  676.     }    // switch (rmFx_Method)    
  677.     return msgReturn;
  678. }
  679.  
  680.     
  681. function reminderFox_addMultipleEvents(reminderEvents, reminderTodos) {    
  682.         // merge
  683.     var existingEvents = reminderFox_getReminderEvents();
  684.     var existingTodos = reminderFox_getReminderTodos();  //  ALL  todos
  685.     var rvEvent = reminderFox_mergeEvents(existingEvents, reminderEvents  );
  686.     var rvTodo = reminderFox_mergeTodos( existingTodos, reminderTodos );
  687.  
  688.     reminderFoxEvents = existingEvents;
  689.     reminderFoxTodosArray = existingTodos;      
  690.    
  691.     reminderFox_importRemindersUpdateAll(false, null );   
  692.     
  693. // write to status !!    
  694.     var msgText =  "Events : " + rvEvent.importNo + " imported  " + rvEvent.existNo + " exists."  
  695.             + "\n" + "Todo's : " + rvTodo.importNo  + " imported  " + rvTodo.existNo + " exists." ;
  696.                 
  697.     rmFxCore.statusSet (msgText);
  698. }
  699.  
  700. //  ------------- GET TODO(s) ------------------------------
  701. /**
  702.  * 
  703.  */
  704. function rmFx_getSelectedTodos () { 
  705.  
  706.     var tabList = document.getElementById("tabList");    
  707.     var tab = tabList.selectedItem;
  708.     var tabLabel =  tab.label;
  709.         
  710.     var todosToBeSend = getAllSelectedTodos();
  711.     
  712.     if (todosToBeSend.length == 0) return;
  713.     //  todosToBeSend[0].extraInfo
  714.     for (var i = 0; i < todosToBeSend.length; i++) {
  715.         if (todosToBeSend[i].extraInfo == null) {
  716.             todosToBeSend[i].extraInfo = REMINDERFOX_EXTENDED + "LISTID:" + tabLabel;
  717.         } else {
  718.             if (todosToBeSend[i].extraInfo.indexOf(REMINDERFOX_EXTENDED + "LISTID") == -1) {
  719.                 todosToBeSend[i].extraInfo += "\\n" + REMINDERFOX_EXTENDED + "LISTID:" + tabLabel;
  720.             }
  721.         }
  722.     }
  723.     var todoArrayArray = new Array();
  724.     todoArrayArray[0] = todosToBeSend;
  725.     
  726.     return todoArrayArray;
  727.  
  728.  
  729.  
  730. //  ------------- SEND / EXPORT  iCal ------------------------------
  731. /**
  732.  *  Send/export one or more 'reminder(s)' as they are
  733.  * 
  734.  * @param selectedReminders 
  735.  * @param organizer         
  736.  * @param mode              if 'xExport' stores reminders to file
  737.  * @param reminderTyp       'reminder' | 'todo'
  738.  *
  739.  */
  740. function rmFx_sendAsItIs (selectedReminders, organizer, mode, reminderTyp) {
  741.     var methodTyp = "ICS";    
  742.     var attendees = null;
  743.  
  744.     if (mode == 'xExport') {    // generate an ICS file here  
  745.      
  746.         if (reminderTyp == 'todo') {
  747.             var iCalString = reminderFox_constructReminderOutput( "", selectedReminders, true, true, "PUBLISH" );            
  748.         }  else {
  749.             var iCalString = reminderFox_constructReminderOutput( selectedReminders, "", true, true, "PUBLISH" );
  750.         } 
  751.         var exportFile = reminderFox_prefsBranch.getCharPref("exportEventsFile");
  752.         
  753.         // rmFxUtil.dump2Console ("gWTEST:  'exportReminders to File'   >>" + exportFile + "<<");         //gWTEST darwin
  754.  
  755.         var iCalToEmailFile = rmFxUtil.makeMsgFile (rmFxUtil.encodeUTF8(iCalString), exportFile);
  756.         if (iCalToEmailFile == null) {
  757.             rmFxUtil.PromptAlert("Export failed. File '" + exportFile + "' path not valid!");
  758.         }
  759.         
  760.         return;
  761.     }
  762.  
  763.     rmFx_sendEventNow(selectedReminders, "", 'ICS' /*methodTyp*/, organizer, attendees, reminderTyp);        
  764.  
  765. var selectedReminders = null;
  766.  
  767. /**
  768.  *   With the selected Reminder/Todo's 
  769.  *     'Export to file' or  'Send a Mail' as an INVITATION/SCHEDULE
  770.  * 
  771.  * @param   event     has '.id' for selected ReminderTyp, if 'null' called from function
  772.  * @param   _selectedTyp        //    'invite'   | 'info'
  773.  * @param   _reminderTyp        //    'reminder' | 'todo'
  774.  * @param   _Reminders          //      
  775.  *
  776.  * @return
  777.  */
  778. function rmFx_ExportOrSend (event, _selectedTyp, _reminderTyp, _Reminders) {
  779.  
  780. //    var selectedReminders="";
  781.     var methodTyp = "PUBLISH";     // default=PUBLISH ... other METHOD:PUBLISH, REQUEST, REPLY
  782.     var attendees = null;
  783.     var organizer = null;
  784.     var selectedTyp;      //    'invite'   | 'info'
  785.     var reminderTyp;      //    'reminder' | 'todo'
  786.     var eventLength;      //    use to show # of events in XUL title     
  787.     
  788.     if (event == null) { // function call (eg. from 'View')
  789.         selectedTyp = _selectedTyp;
  790.         reminderTyp = _reminderTyp;
  791.         selectedReminders = _Reminders;
  792.         eventLength = selectedReminders.length;
  793.         
  794.     } else {  // called from ReminderList popup menu 
  795.  
  796.         if (event.currentTarget.id == "treechildren-contextmenu-sendReminder")  {
  797.             selectedTyp = 'invite'; 
  798.             reminderTyp = 'reminder';
  799.             
  800.             selectedReminders = getAllSelectedReminders();
  801.             var eventLength = selectedReminders.length;
  802.             if (eventLength == 0) return;  // no reminders selected!
  803.                     
  804.             if (selectedReminders.length > 1)  {
  805.                 selectedTyp = 'info';   // only 'single' events can be send as invitation
  806.             }
  807.         } 
  808.     
  809.         if (event.currentTarget.id == "treechildren-contextmenu-sendTodos") {
  810.             selectedTyp = 'info'; 
  811.             reminderTyp = 'todo';
  812.     
  813.             selectedReminders = rmFx_getSelectedTodos();
  814.  
  815.             if (selectedReminders == null) {
  816.                 rmFxCore.statusSet (reminderFox_getBundle().getString("rf.schedule.resendwithDialog")) // ("No Todo's selected!"); 
  817.                 return;
  818.             }
  819.             
  820.             var eventLength = selectedReminders[0].length;
  821.         } 
  822.     }
  823.     
  824.     if (selectedTyp == 'invite') {
  825.         
  826.     /*  have to check if the selected "Reminder" was already send as invitation/schedule;
  827.      *  that's the case if ORGANIZER is already included in "selectedReminders"
  828.      */
  829.         if (selectedReminders[0].extraInfo!= null) { 
  830.             if (selectedReminders[0].extraInfo.indexOf("ORGANIZER") != -1) { 
  831.                 var msg = reminderFox_getBundle().getString("rf.schedule.wasSend") 
  832.                     + "\n"   + reminderFox_getBundle().getString("rf.schedule.resendwithDialog")    
  833.                     + "\n\n" + reminderFox_getBundle().getString("rf.schedule.sendAsEvent");
  834.                 
  835.                 if (confirm(msg) == false) {    
  836.                     var msg =         reminderFox_getBundle().getString("rf.schedule.wantDelete")
  837.                         + "\n\n"+     reminderFox_getBundle().getString("rf.schedule.okDelete");
  838.                     
  839.                     if (confirm(msg ) == true) {  // this is the 'delete invitation' part 
  840.                     
  841.                         var extraInfoArrayInv = rmFx_extraInfoArray(selectedReminders[0]);
  842.                         var extraInfoArray = new Array ();    var j=0;
  843.                         
  844.                         for (var i=0; i < extraInfoArrayInv.length; i++) {
  845.                             if (extraInfoArrayInv[i].indexOf("ORGANIZER")    > -1 ||
  846.                                 extraInfoArrayInv[i].indexOf("ATTENDEE")        > -1 ||
  847.                                 extraInfoArrayInv[i].indexOf("DTSTAMP")        > -1 ||
  848.                                 extraInfoArrayInv[i].indexOf("STATUS")            > -1 ||
  849.                                 extraInfoArrayInv[i].indexOf("CLASS")            > -1 ||
  850.                                 extraInfoArrayInv[i].indexOf("COMMENT")        > -1 ||
  851.                                 extraInfoArrayInv[i].indexOf("SEQUENCE")        > -1 )
  852.                                 { 
  853.                                 } else {
  854.                                 extraInfoArray[j] = extraInfoArrayInv[i]; j++;    
  855.                             }                            
  856.                         }
  857.                         // delete the 'invitation' category also
  858.                         var xCategories = selectedReminders[0].categories;
  859.                         
  860.                         var iCalCategory = reminderFox_getBundle().getString("rf.mail.ical.send.subject.invitation"); //   "invitation";
  861.                         if (xCategories.indexOf(iCalCategory) > -1) {
  862.                             selectedReminders[0].categories = xCategories.replace(iCalCategory, '');
  863.                         }
  864.                         
  865.                         // write the selectedReminder back to currentReminder without 'extra' strings                    
  866.                         selectedReminders[0].extraInfo= extraInfoArray.join("\n");
  867.                         var reminderTodos=null;
  868.                         reminderFox_addMultipleEvents(selectedReminders, reminderTodos)
  869.     
  870.                         rmFxUtil.PromptAlert(reminderFox_getBundle().getString("rf.schedule.hasDeleted")
  871.                               + "\n\n" + reminderFox_getBundle().getString("rf.schedule.checkDeleted"));
  872.                     }
  873.                     return;
  874.                 } 
  875.                 selectedTyp ='info';  // was already send, don't allow to send as 'invite'
  876.             }
  877.         }
  878.     }
  879.     // Reminder(s)  'send' or 'export'
  880.     //   if 'CANCEL' or 'close window' pressed -->> terminate    
  881.     var results = {    organizer: null, 
  882.                     attendees: null, 
  883.                     mode: null, 
  884.                     selectedTyp: selectedTyp,
  885.                     reminderTyp: reminderTyp,
  886.                     eventLength: eventLength,
  887.                     schComment: ""};
  888.     window.openDialog("chrome://reminderfox/content/mail/invitation.xul",
  889.                 "reminderFox-set-invitationmailAppString", "chrome,resizable,modal", results);        
  890.  
  891.     if (results.mode == 'CANCEL') return;    
  892.     
  893.     if (results.mode == 'xExport') {         // export to ICS file 
  894.         rmFx_sendAsItIs (selectedReminders, results.organizer, results.mode, reminderTyp)
  895.         return;
  896.     }
  897.  
  898.     if (results.selectedTyp == 'info') {    // send "as-it-is" ===> PUBLISH
  899.     //    rmFx_sendAsItIs (selectedReminders, results.organizer, results.mode, reminderTyp);
  900.     
  901.         var attendees = null;
  902.         if (reminderTyp == 'reminder') {
  903.         // this.selectedReminders[0].url $[1] = [string] "mailto:abc@xyz.de"
  904.             if (this.selectedReminders.length == 1) {
  905.                 if (this.selectedReminders[0].url.indexOf('mailto:') == 0) 
  906.                     attendees = this.selectedReminders[0].url.substring(7);
  907.             }
  908.             rmFx_sendEventNow(selectedReminders, "", 'ICS' /*methodTyp*/, organizer, attendees, reminderTyp);    
  909.         }    
  910.         if (reminderTyp == 'todo') {
  911.         // this.selectedReminders[0][0].url $[1] = [string] "mailto:abc@xyz.de"
  912.             if (this.selectedReminders[0].length == 1) {
  913.                 if (this.selectedReminders[0][0].url.indexOf('mailto:') == 0) 
  914.                     attendees = this.selectedReminders[0][0].url.substring(7);
  915.             }
  916.             rmFx_sendEventNow("", selectedReminders,  'ICS' /*methodTyp*/, organizer, attendees, reminderTyp);
  917.         }
  918.         return;
  919.     }
  920.  
  921.     //    send  INVITATION/SCHEDULE  ===> REQUEST
  922.     if (results.selectedTyp == 'invite') {methodTyp = 'REQUEST';}    
  923.                  
  924.     organizer = results.organizer;
  925.     if (organizer == "") {
  926.         rmFxUtil.PromptAlert(reminderFox_getBundle().getString("rf.schedule.organizer.required")
  927.         + "\n" + reminderFox_getBundle().getString("rf.schedule.organizer.mailAdr"));
  928.         return;
  929.     }    
  930.  
  931.     if (results.attendees != null && results.attendees != "") {
  932.         methodTyp = "REQUEST";         // attendees where entered --> REQUEST
  933.         } else {
  934.         methodTyp = "PUBLISH";     
  935.     }
  936.     //  add invitation info to 'extraInfo' item
  937.     var originalReminder = selectedReminders[0];    
  938.     var updatedReminder = reminderFox_cloneReminderFoxEvent(selectedReminders[0] );    
  939.  
  940.     if ( updatedReminder.extraInfo == null ) { 
  941.         updatedReminder.extraInfo = "";
  942.     }
  943.     else {
  944.         updatedReminder.extraInfo += "\\n";
  945.     }
  946.     //2008-12-16   clear trailing/leading spaces
  947.     var organizerName = reminderFox_trim(organizer.split("<")[0]);
  948.     var organizerMail = reminderFox_trim(organizer.split("<")[1]);
  949.  
  950.     if (organizerMail == null) {
  951.             organizerMail = organizerName;
  952.             organizerName ="";
  953.     }                         
  954.     if (organizerMail.charAt(organizerMail.length-1) == ">") {
  955.         organizerMail = organizerMail.substring(0,organizerMail.length-1)
  956.     }
  957.     var xString ="ORGANIZER";
  958.     if (organizerName != "") {xString += ";CN=" + organizerName}
  959.     if (organizerMail != "") {xString += ":MAILTO:" + organizerMail}
  960.          
  961.     updatedReminder.extraInfo = updatedReminder.extraInfo + xString;
  962.     
  963.     // add SEQUENCE=1 and DTSTAMP (current date/time in 'Z'
  964.     var currentDate = new Date();
  965.     var tzOffset = new Date().getTimezoneOffset(); 
  966.     currentDate.setMinutes( currentDate.getMinutes() + tzOffset );                        
  967.          
  968.     var dtStamp = reminderFox_getDateAsString(currentDate)+ "Z";   
  969.     updatedReminder.extraInfo += "\\nSEQUENCE:" + 1 +"\\nDTSTAMP:" + dtStamp;
  970.  
  971.     // add ATTENDEE(s)
  972.     if (methodTyp == "REQUEST") {
  973.         attendees = results.attendees.replace(/(^\s+)|(\s+$)/g, '');       
  974.  
  975.         if ( updatedReminder.extraInfo == null ) { 
  976.                 updatedReminder.extraInfo = "";
  977.         }  else {
  978.                 updatedReminder.extraInfo += "\\n";
  979.         }
  980.         //    ATTENDEE;RSVP=TRUE:MAILTO:abcde@fghi.xx          
  981.         var attendeeArray = attendees.split(",");
  982.         for ( var i = 0; i < attendeeArray.length; i++  ) {
  983.             if (attendeeArray[i] == "") {break;}                  
  984.             var attendeeMail ="";
  985.             var attendeeName ="";
  986.                 
  987.             var attendeeX = attendeeArray[i].split("<");                  
  988.             if (attendeeX.length == 1) {    // only mailAdr
  989.                 var attendeeMail = attendeeX[0].replace(/(^\s+)|(\s+$)/g, '').replace(">", '');
  990.             } else {                        // mailName and adr
  991.                 var attendeeName = attendeeX[0].replace(/(^\s+)|(\s+$)/g, '');
  992.                  var attendeeMail = attendeeX[1].replace(/(^\s+)|(\s+$)/g, '').replace(">", '');
  993.             }                        
  994.             var xString ="ATTENDEE";
  995.             if (attendeeName != "") {xString += ";CN=" + attendeeName}
  996.             if (attendeeMail != "") {xString += ";RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:MAILTO:" + attendeeMail}
  997.                 
  998.             if ( i != 0 ) {
  999.                 updatedReminder.extraInfo += "\\n";
  1000.             }
  1001.             updatedReminder.extraInfo = updatedReminder.extraInfo + xString; 
  1002.         }
  1003.     }
  1004.  
  1005.     // add 'comment'  from invitation.xul dialog
  1006.     if (results.schComment != "") {
  1007.         updatedReminder.extraInfo += "\\nCOMMENT:" + results.schComment;
  1008.     }
  1009.     // add other items 
  1010.     reminderFox_processExtraScheduleInfo(updatedReminder, "", methodTyp );
  1011.     
  1012.     // add category                                 
  1013.     var iCalCategory = reminderFox_getBundle().getString("rf.mail.ical.send.subject.invitation"); //   "invitation";  
  1014.     var iCalCategoryLC = iCalCategory.toLowerCase(); //   "invitation";  
  1015.     if ( updatedReminder.categories != null && updatedReminder.categories.length > 0 ) {
  1016.         if (updatedReminder.categories.toLowerCase().indexOf(iCalCategoryLC) == -1){
  1017.              updatedReminder.categories = updatedReminder.categories + ", " + iCalCategory;}
  1018.              
  1019.     } else { updatedReminder.categories = iCalCategory;
  1020.     }
  1021.  
  1022.     //  REPLACE the current entry 
  1023.     removeListItemsForReminder(originalReminder); 
  1024.     // remove from model list
  1025.     var reminders = reminderFox_getReminderEvents();    
  1026.     for( var i = 0; i < reminders.length; i++) {
  1027.         if ( reminders[i].id == originalReminder.id ) {
  1028.             reminderFox_removeElement(reminders, i);
  1029.             break;
  1030.         }
  1031.     }
  1032.  
  1033.     // add reminder in sorted order...
  1034.     reminders = reminderFox_getReminderEvents();                    
  1035.     if ( updatedReminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) {
  1036.         updatedReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  1037.     }                
  1038.     var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, updatedReminder, false );
  1039.     reminderFox_insertIntoArray( reminders, updatedReminder, sortedIndex );
  1040.     
  1041.     updatedReminder.snoozeTime = null;                  
  1042.     createListItem(updatedReminder);            
  1043.  
  1044.     var currentDate = oeDatePicker.gSelectedDate;
  1045.     if ( currentDate == null ) {
  1046.         currentDate = new Date();
  1047.     }    
  1048.  
  1049.     var newDate = new Date();
  1050.     if ( updatedReminder.alarm != null ) {
  1051.         updatedReminder.alarmLastAcknowledge = newDate.getTime();
  1052.         // if there's a snooze... and lastack > snooze, erase snooze...  
  1053.         // this means...  well it should be if date changed at all, then need to clear snooze...
  1054.     }
  1055.     updatedReminder.lastModified = reminderFox_getDateAsString(newDate );
  1056.     var reminder = reminderFox_processReminderDescription(updatedReminder,  currentDate.getFullYear(), false);        
  1057.     var modified = updateReminderInList( reminder );
  1058.     sortReminderIfNeccessary( updatedReminder.id);
  1059.  
  1060.     refreshCalendar();
  1061.     modifiedReminders();
  1062.  
  1063.     selectedReminders[0] = updatedReminder;        // need array    
  1064.     rmFx_sendEventNow(selectedReminders, "", methodTyp, organizer, attendees, selectedTyp);
  1065. }
  1066.  
  1067. /**
  1068.  * Preparing the message content and passing to the send or compose mail function
  1069.  * 
  1070.  * @param reminderToBeSend    passed as array!!
  1071.  * @param todosToBeSend        passed as array!!
  1072.  * @param methodTyp            'PUBLISH' | 'REQUEST' | 'REPLY' | 'ICS' (for sending 'view')
  1073.  * @param fromAddress
  1074.  * @param attendees
  1075.  * @param selectedTyp        'invite' = send one event as invitation | 'info' = send one/more event
  1076.  * @return
  1077.  */
  1078. function rmFx_sendEventNow(reminderToBeSend, todosToBeSend, methodTyp, fromAddress, attendees, selectedTyp) { 
  1079.  
  1080.     var statusMsg = "";
  1081.     if ((fromAddress != "") && (fromAddress != null)) {
  1082.         statusMsg += reminderFox_getBundle().getString("rf.mail.ical.sendby") 
  1083.                      + " " + fromAddress;
  1084.     }    else {
  1085.         statusMsg += reminderFox_getBundle().getString("rf.mail.ical.send")  + " ";        // "Sending"
  1086.     }         
  1087.     statusMsg += " " + reminderFox_getBundle().getString("rf.mail.ical.sending");
  1088.     rmFxCore.statusSet (statusMsg);
  1089.  
  1090.     var footer = "  " + "______________________________________________________\n" 
  1091.                         + reminderFox_getBundle().getString("rf.mail.ical.send.body");
  1092.  
  1093.     // --- setup parameters for message ----------------- 
  1094.     var eMailSubject ="";
  1095.  
  1096.     if (methodTyp == "ICS") {
  1097.         eMailSubject = "[ics]  ";
  1098.     }    
  1099.     if (methodTyp == "PUBLISH") {
  1100.         eMailSubject = "[iCal]  " + methodTyp + ": ";        // $$$locale  iCal PUBLISH
  1101.     }
  1102.  
  1103.     if ((reminderToBeSend != null) && (reminderToBeSend != "")) {
  1104.         var uid = reminderToBeSend[0].id;
  1105.         var extraInfo = rmFx_extraInfoArray(reminderToBeSend[0]);
  1106.         
  1107.         if (selectedTyp == 'reminder') { methodTyp = "PUBLISH"; }
  1108.         var iCalString = reminderFox_constructReminderOutput( reminderToBeSend, "", true, true, methodTyp ); 
  1109.     }
  1110.     
  1111.     if ((todosToBeSend != null) && (todosToBeSend != "")) {
  1112.         var uid = todosToBeSend[0][0].id;
  1113.         var extraInfo = "";
  1114.         if (selectedTyp == 'todo') { methodTyp = "PUBLISH"; }
  1115.         var iCalString = reminderFox_constructReminderOutput( "", todosToBeSend, true, true, methodTyp ); 
  1116.     }
  1117.  
  1118.     
  1119.     if (methodTyp == 'REQUEST' ) {
  1120.         eMailSubject = "[iCal]  " + methodTyp + ": ";    //$$$locale  iCal eg. REQUEST
  1121.         selectedTyp = 'invite';
  1122.     }    
  1123.     if (methodTyp == 'REPLY') {
  1124.         eMailSubject = "[iCal]  ";
  1125.         selectedTyp = 'invite';
  1126.  
  1127.         var xAtt =rmFx_extraInfoArray(reminderToBeSend[0]);
  1128.         var Item = "ATTENDEE";
  1129.         var attPart="";
  1130.         if (xAtt != null) {
  1131.             if (xAtt.length > -1) {
  1132.                 for (var n =0; n < xAtt.length; n++) {    
  1133.                     if (xAtt[n].indexOf( Item )  == 0) {                        
  1134.                         var fnd =  xAtt[n].indexOf("PARTSTAT=");
  1135.                         if (fnd != -1) {
  1136.                             var attPart = xAtt[n].substring(fnd+9);
  1137.                             fnd = attPart.indexOf(";");
  1138.                             if (fnd == -1) {attPart.indexOf(":")};
  1139.                             var attPart = attPart.substring(0,fnd);    
  1140.                         }
  1141.                     }
  1142.                 }
  1143.             }
  1144.         }
  1145.         eMailSubject +=  attPart  + ": ";        //$$$locale     iCal eg. ACCEPTED / DECLINED
  1146.     }  
  1147.     
  1148.     ////////////////// 'invite' was selected ////////////////////////////////////
  1149.     // sending without extra compose
  1150.     if (selectedTyp == 'invite') {  
  1151.         eMailSubject += reminderToBeSend[0].summary 
  1152.                 + " / " + reminderFox_getBundle().getString("rf.schedule.statusOf")
  1153.                 + " "   + reminderFox_parseDateTimes(rmFx_extraInfo(extraInfo,"DTSTAMP"))
  1154.                 + " [#" + rmFx_extraInfo(extraInfo,"SEQUENCE") +"]";
  1155.                 
  1156.         var body  = "*" + reminderFox_getBundle().getString("rf.mail.ical.send.subject.invitation") 
  1157.             + "*  ┬╗" + reminderToBeSend[0].summary  + "┬½"
  1158.              + "\n"    + reminderFox_getBundle().getString("rf.mail.ical.send.sentBy") + "  " + fromAddress + "\n";
  1159.  
  1160.         // setup for different invitation items ....
  1161.             function addBody (option, optText) {
  1162.                 return ((option == null) || (option == ""))
  1163.                     ? ""
  1164.                     : "\n" + optText + option;
  1165.             }
  1166.         var priority = reminderToBeSend[0].priority;
  1167.         var priorityStr = (priority == 1) 
  1168.             ? reminderFox_getBundle().getString("rf.add.mail.message.priority")
  1169.             : "";
  1170.  
  1171.         body += addBody (priorityStr, "*" + reminderFox_getBundle().getString("rf.add.mail.message.priority.label")+ "*  ");
  1172.         body += addBody (reminderToBeSend[0].location, "*" + reminderFox_getBundle().getString("rf.mail.ical.send.location") + "* ");
  1173.         body += addBody (reminderToBeSend[0].url, "*" + reminderFox_getBundle().getString("rf.add.reminders.tooltip.url") + "* ");
  1174.         body += addBody (reminderToBeSend[0].notes, "\n*" + reminderFox_getBundle().getString("rf.add.mail.message.notes") 
  1175.                                         +"* ___________________________ \n");                
  1176.         
  1177.         /** ---------- sending without extra compose --------------------------**/
  1178.         var tmpMsgFile =     rmFxMsg.FileCreate( 
  1179.                                         eMailSubject, 
  1180.                                         fromAddress, 
  1181.                                         attendees,
  1182.                                         priority,  
  1183.                                         body,
  1184.                                         footer, 
  1185.                                         uid, 
  1186.                                         iCalString, methodTyp);
  1187.  
  1188.         rmFxMsg.FileSend (eMailSubject, 
  1189.                                 fromAddress, 
  1190.                                 attendees,
  1191.                                 priority,        
  1192.                                 tmpMsgFile,
  1193.                                 uid);
  1194.                             
  1195.         rmFxCore.statusSet (reminderFox_getBundle().getString("rf.mail.ical.sendby") + " " + fromAddress);         //  "Send by"
  1196.         return;            
  1197.     }
  1198.  
  1199.     /* ---------- not used ???? ------------------------------------------------
  1200.     ////////////////// 'info' was selected ////////////////////////////////////
  1201.     // sending one or more reminders, go for compose
  1202.     
  1203.     if (selectedTyp == 'info') {  // used with 'SendAsItIs' and 'multiple' events
  1204.         // ** differentiate:  one event:: just take the summary as subject
  1205.         // ** no ATTENDEES (toAddress) ... have to add with 'composemessage'
  1206.         
  1207.         var body  = reminderFox_getBundle().getString("rf.add.mail.message.body");
  1208.                         
  1209.         if (reminderToBeSend.length == 1) {
  1210.             eMailSubject += reminderToBeSend[0].summary; 
  1211.             
  1212.             body  +=  ":  " + eMailSubject
  1213.                     +  "\n"    + reminderFox_getBundle().getString("rf.mail.ical.send.sentBy") + "  " + fromAddress 
  1214.                     +  "\n" + reminderFox_getBundle().getString("rf.add.mail.message.subject") 
  1215.                     +  "\n\n";    
  1216.                             
  1217.         } else {  //     more than one events:: only give # of events
  1218.             eMailSubject += reminderFox_getBundle().getString("rf.schedule.event.send") 
  1219.                         + " (" + reminderToBeSend.length +")";
  1220.  
  1221.             body  += "\n\n"    + reminderFox_getBundle().getString("rf.mail.ical.send.sentBy") + "  " + fromAddress +"\n";
  1222.         }
  1223.         // ---------- compose ------------------------------------------------
  1224.         var iCalFile =   reminderFox_getReminderStoreFile();
  1225.         iCalFile.leafName = "reminderfoxEvents.ics";
  1226.     
  1227.  
  1228.         //      rmFxUtil.dump2Console ("gWTEST: 'info'  msg Compose iCalToEmailFile >>" +iCalFile.path+ "<<");            //gWTEST darwin    
  1229.  
  1230.  
  1231.         var iCalToEmailFile = rmFxUtil.makeMsgFile (rmFxUtil.encodeUTF8(iCalString), iCalFile.path);
  1232.         
  1233.         if (iCalToEmailFile == null) {
  1234.             rmFxUtil.PromptAlert("Compose failed. File '" + iCalFile.path + "' path not valid!");
  1235.             return;
  1236.         }
  1237.         rmFxMsg.Compose(eMailSubject, fromAddress,  attendees,
  1238.             priority, body, footer, uid, iCalToEmailFile, methodTyp);
  1239.  
  1240.  
  1241.         rmFxCore.statusSet (reminderFox_getBundle().getString("rf.add.mail.message.compose")) / *"Compose message"* /
  1242.                 + "  ("  + fromAddress + ")";
  1243.         return;
  1244.     }
  1245.     --------- not used ?? --------------*/ 
  1246.             
  1247.     /////////// 'reminder' or 'todo' has been selected /////////////
  1248.     //  go for compose
  1249.     //     one event: just take the reminder.summary as 'subject'
  1250.     //     no ATTENDEES (toAddress) ... have to add with 'composemessage'
  1251.     
  1252.     // prepare 'body' and 'subject' of message
  1253.     
  1254.     var body  = reminderFox_getBundle().getString("rf.add.mail.message.body") + "\n";
  1255.  
  1256.     if ((fromAddress != "") && (fromAddress != null)) {
  1257.         body  +=  reminderFox_getBundle().getString("rf.mail.ical.send.sentBy") 
  1258.                 + "  " + fromAddress +"\n";
  1259.     } 
  1260.                     
  1261.     var _subject = "";                
  1262.     if (selectedTyp == 'todo') {                                
  1263.         if (todosToBeSend[0].length == 0) {
  1264.             statusMsg = reminderFox_getBundle().getString("rf.mail.ical.noitems");
  1265.             rmFxCore.statusSet (statusMsg);
  1266.             return;  // no todo's selected
  1267.         }
  1268.         if (todosToBeSend[0].length == 1) {    
  1269.             _subject = todosToBeSend[0][0].summary
  1270.         } else {
  1271.             _subject = todosToBeSend[0].length;
  1272.         }
  1273.     } 
  1274.     if (selectedTyp == 'reminder') { 
  1275.         if (reminderToBeSend.length == 0) {
  1276.             statusMsg = reminderFox_getBundle().getString("rf.mail.ical.noitems"); //"No items to be send."
  1277.             rmFxCore.statusSet (statusMsg);    
  1278.             return;}    // no events selected
  1279.         if (reminderToBeSend.length == 1) {
  1280.             _subject = reminderToBeSend[0].summary
  1281.         } else {
  1282.             _subject = reminderToBeSend.length; 
  1283.         }
  1284.     }
  1285.     var msgInfo = reminderFox_getBundle().getString("rf.schedule.event.send." + selectedTyp)
  1286.             + " :  " + _subject;    
  1287.             
  1288. //    var viewLabel; 
  1289. //    (rmFxViewLabel != "")
  1290. //            ? viewLabel=(" [" + reminderFox_getBundle().getString("rf.views.name") + ": " + rmFxViewLabel + "] : ") 
  1291. //            : viewLabel=(" : ");    
  1292.     // body  += selectedTyp.toUpperCase() + viewLabel + _subject + "\n\n";    
  1293.     body  += msgInfo + "\n\n";    
  1294.                     
  1295.     eMailSubject += msgInfo;
  1296.         
  1297.  
  1298.     // ---------- compose ------------------------------------------------
  1299.     var iCalFile =   reminderFox_getReminderStoreFile();
  1300.     iCalFile.leafName = "reminderfoxEvents.ics";
  1301.  
  1302.     // rmFxUtil.dump2Console ("gWTEST:  msg Compose iCalToEmailFile >>" +iCalFile.path+ "<<");            //gWTEST darwin    
  1303.  
  1304.     var iCalToEmailFile = rmFxUtil.makeMsgFile (rmFxUtil.encodeUTF8(iCalString), iCalFile.path);
  1305.     if (iCalToEmailFile == null) {
  1306.         rmFxUtil.PromptAlert("Compose failed. File '" + iCalFile.path + "' path not valid!");
  1307.         return;
  1308.     }
  1309.  
  1310.     rmFxMsg.Compose(eMailSubject, fromAddress,  attendees,
  1311.         priority, body, footer, uid, iCalToEmailFile, methodTyp);
  1312.  
  1313.     rmFxCore.statusSet (reminderFox_getBundle().getString("rf.add.mail.message.compose")) /*"Compose message"*/
  1314. }
  1315.  
  1316. function reminderFox_parseDateTimes(stringDT) { /*  20051208T224616  or  20051208T224616Z = UTC */
  1317.      var thisDate = reminderFox_getStringAsDate(stringDT);
  1318.      
  1319.     var timeString = reminderFox_mail_getTimeString( thisDate );
  1320.     var dateVariableString;
  1321.     try {
  1322.         dateVariableString = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LIST_DATE_LABEL);
  1323.     } catch(e) {
  1324.     }
  1325.     var remFoxDate =reminderFox_getDateVariable( null, thisDate, dateVariableString ) + "  " + timeString;
  1326.     return remFoxDate;
  1327.  
  1328.     return stringDT;
  1329. }
  1330.  
  1331. function rmFx_extraInfoArray(reminder){
  1332. /* ------ converts the extraInfo string to an array 
  1333.  */
  1334.     if  (!!reminder.extraInfo) {
  1335.         var extraInfoArray = reminder.extraInfo.split("\\n");      
  1336.         return extraInfoArray;  
  1337.     } else {
  1338.         return null;
  1339.     }
  1340. }
  1341.  
  1342.  
  1343. function rmFx_extraInfo(extraInfos, item, delimiter, multiple){  // if multiple==true --> build array
  1344. // ------ reads from extraInfos array using item 
  1345.     if (delimiter == null) delimiter = ":";
  1346.     var Item = item.toUpperCase();
  1347.     var result="";
  1348.     if (extraInfos != null) {
  1349.         if (extraInfos.length > -1) {
  1350.             for (var n =0; n < extraInfos.length; n++) {
  1351.                 if (extraInfos[n].indexOf( Item )  == 0) {
  1352.                     if (multiple) {result +=  extraInfos[n].substring(extraInfos[n].indexOf( delimiter ) +1 ) + "\n"; 
  1353.                     } else {
  1354.                         result =  extraInfos[n].substring(extraInfos[n].indexOf( delimiter ) +1); 
  1355.                         break;
  1356.                     }
  1357.                 }
  1358.             }
  1359.         }
  1360.     }
  1361.     return result;
  1362. }
  1363.  
  1364.  
  1365. //============================================================
  1366.  
  1367. // -------- select Attendee from menu -----------------
  1368.  
  1369. function rmFx_replyAttDialogClose() {
  1370.     window.arguments[0].attendeeNo = 
  1371.         document.getElementById('rmFx_replyAttendeeGroup').selectedIndex;
  1372. }        
  1373. function rmFx_replyAttDialogCancel() {
  1374.     window.arguments[0].attendeeNo = -1;
  1375. }        
  1376.  
  1377. function rmFx_replyAttendeeAdd() {
  1378.     var attendeesList = window.arguments[0].attendees;
  1379.     var attGroup = document.getElementById("rmFx_replyAttendeeGroup");
  1380.     for ( var i = 0; i < attendeesList.length; i++ ) {    
  1381.         
  1382.         var fndIndex = attendeesList[i].toUpperCase().lastIndexOf( "MAILTO:" ); 
  1383.         if (fndIndex != -1) {
  1384.             var fndString =  attendeesList[i].substring( fndIndex + 7);
  1385.                                                         
  1386.             var e = document.createElement("radio");
  1387.                 e.setAttribute("group", "rmFx_replyAttendeeGroup");
  1388.                 e.setAttribute("label", fndString);
  1389.             attGroup.appendChild(e);
  1390.         }
  1391.     }
  1392. }
  1393.  
  1394. // ---- setup 'mail-app' and 'myAccounts' ---- (for FX) ----
  1395. function rmFx_mailAppSetup() {
  1396.  
  1397.     var results = { organizer:     null, 
  1398.                         attendees:        null, 
  1399.                         mode:             'mailApp', 
  1400.                         selectedTyp:     'info',
  1401.                         schComment:     ''};
  1402.     window.openDialog("chrome://reminderfox/content/mail/invitation.xul",
  1403.                 "reminderFox-set-invitationmailAppString", "chrome,resizable,modal", results);        
  1404.  
  1405.     if (results.mode == 'CANCEL') { return 'CANCEL';} // user pressed 'CANCEL'
  1406.  
  1407.     return     reminderFox_prefsBranch
  1408.                 .getCharPref(REMINDER_FOX_MAIL_SENDER);
  1409. }
  1410.  
  1411. // ---- setup 'mail-app' and 'myAccounts' ---- (for FX) ----
  1412. function rmFx_sendExportDialog() {
  1413.  
  1414.     var results = { organizer:  null, 
  1415.                     attendees:      null, 
  1416.                     mode:           'mailApp', 
  1417.                     selectedTyp:    'info',
  1418.                     schComment:     ''};
  1419.     window.openDialog("chrome://reminderfox/content/mail/invitation.xul",
  1420.                 "reminderFox-set-invitationmailAppString", "chrome,resizable,modal", results);        
  1421.  
  1422.     if (results.mode == 'CANCEL') { return 'CANCEL';} // user pressed 'CANCEL'
  1423.  
  1424.     return  results;
  1425. }
  1426.  
  1427. // ---- invitation XUL dialogs -------------
  1428.           
  1429. function rmFx_invitationLoadDialog() {
  1430.         
  1431.     if (window.arguments[0].mode == "mailApp") {
  1432.          this.title = reminderFox_getBundle().getString("rf.schedule.setDefaults");
  1433.     }
  1434.  
  1435.     var orgMenu= document.getElementById('organizerMenu');
  1436.  
  1437.     //  with rmFxMsg.myMailIDs the mailIdentities/organizer 
  1438.     //  and the mailApplication location are checked and read
  1439.     var myAccount = rmFxMsg.myMailIDs();
  1440.  
  1441.     if (!!myAccount) {
  1442.         var myAccounts = myAccount.split(",");
  1443.         for (var i = 0; i < myAccounts.length; i++) {
  1444.              var myAccount = myAccounts[i];
  1445.              var menuitem = orgMenu.appendItem(myAccount, i);
  1446.         }
  1447.         orgMenu.selectedIndex = 0;
  1448.     }
  1449.                 
  1450.     // with TB/SM the pulldown menu is NOT editable !!!
  1451.     if (rmFxMsg.messenger()) {
  1452.          document.getElementById('organizerMenu').removeAttribute( "editable");
  1453.          
  1454.             //     document.getElementById('reminderFox-mailApp.Location-Box')        /* //gWTEST DARWIN  do not hide for testing */
  1455.             //            .setAttribute( "hidden", true);
  1456.     }
  1457.     
  1458.     try {
  1459.         var rmFx_exportFile = reminderFox_prefsBranch.getCharPref("exportEventsFile");
  1460.     } catch (ex) {rmFx_exportFile = "reminderfoxEvents.ics";}    
  1461.     
  1462.     document.getElementById("exportFile").setAttribute ("value", rmFx_exportFile);
  1463.     
  1464.  
  1465.     if (window.arguments[0].reminderTyp == 'reminder') {
  1466.         document.title = document.title 
  1467.            + " :  " + reminderFox_getBundle().getString("rf.html.heading.reminders")      /*Reminders*/
  1468.            + " (" + window.arguments[0].eventLength + ") ";                     /*Todo's*/
  1469.     } else {
  1470.         document.title = document.title 
  1471.            + " :  " + reminderFox_getBundle().getString("rf.html.heading.todos") 
  1472.            + " (" + window.arguments[0].eventLength + ") ";             
  1473.     }
  1474.  
  1475.     rmFx_invitationSwitch();  // setting to 'Export'
  1476. }    
  1477.  
  1478.  
  1479. function rmFx_invitationCloseDialog(mode) {  // mode = CANCEL or OK
  1480.  
  1481.     if (mode == 'CANCEL') {
  1482.         window.arguments[0].mode = mode;
  1483.         return;
  1484.     }
  1485.     
  1486.     if (document.getElementById('sendSection').checked) {
  1487.  
  1488.         window.arguments[0].mode = 'xSend';
  1489.     
  1490.         var organizer = document.getElementById('organizerMenu').label;
  1491.         
  1492.         if ((organizer == "") && (organizer.indexOf('<') == -1) && (organizer.indexOf('>') == -1)) {
  1493.             organizer = "<" + organizer + ">";
  1494.         }
  1495.         window.arguments[0].organizer = organizer;
  1496.         
  1497.         reminderFox_prefsBranch.setCharPref(REMINDER_FOX_MAIL_SENDER, organizer);
  1498.             
  1499.         if (document.getElementById('inviteEnable').checked == true) {
  1500.             window.arguments[0].selectedTyp = 'invite';        
  1501.             window.arguments[0].attendees = document.getElementById('attendees').value;
  1502.         } else {
  1503.             window.arguments[0].selectedTyp = 'info';
  1504.             window.arguments[0].attendees = "";
  1505.         }
  1506.         
  1507.         if ( document.getElementById('commentText').value != "") {
  1508.             window.arguments[0].schComment  = document.getElementById('commentText').value;
  1509.         }else {
  1510.             window.arguments[0].schComment  = "";
  1511.         } 
  1512.         
  1513.         var mailApp = document.getElementById('mailApp.location.input').value
  1514.         reminderFox_prefsBranch.setCharPref(REMINDER_FOX_MAIL_PATH, mailApp);        
  1515.     }
  1516.      
  1517.     if (document.getElementById('exportSection').checked) {
  1518.  
  1519.         window.arguments[0].mode = 'xExport';
  1520.         window.arguments[0].selectedTyp = 'info';
  1521.         
  1522.         var exportFile = document.getElementById('exportFile').value;
  1523.         
  1524.         var prefsName = "exportEventsFile"    // set as prefs 'extensions.reminderFox.exportEventsFile'
  1525.         reminderFox_prefsBranch.setCharPref(prefsName, exportFile);
  1526.     }
  1527. }         
  1528.             
  1529. function rmFx_invitationSwitch() {
  1530.  
  1531.     if (window.arguments[0].selectedTyp == 'info') {
  1532.                 
  1533.         document.getElementById('reminderFox-invitationGroup')
  1534.             .setAttribute( "hidden", true );
  1535.         document.getElementById('reminderFox-commentGroup')
  1536.             .setAttribute( "hidden", true );
  1537.         sizeToContent();
  1538.         
  1539.         rmFx_sendExportChange("exportSection");
  1540.         return;
  1541.     } 
  1542.     
  1543.     if ( document.getElementById('inviteEnable').checked ==  true ) {                    
  1544.         document.getElementById('reminderFox-commentGroup')
  1545.                     .setAttribute( "hidden", false );
  1546.         document.getElementById('reminderFox-attendeeGroup')
  1547.                     .setAttribute( "hidden", false );                  
  1548.     }
  1549.     
  1550.     if ( document.getElementById('inviteEnable').checked ==  false ) {
  1551.         document.getElementById('reminderFox-commentGroup')
  1552.             .setAttribute( "hidden", true );
  1553.         document.getElementById('reminderFox-attendeeGroup')
  1554.             .setAttribute( "hidden", true );            
  1555.     }
  1556.  
  1557.     sizeToContent();
  1558. }
  1559.  
  1560.  
  1561. // --------- functions for TB,SM   ... and 'non' mail (like FX)  ---------
  1562.  
  1563. /*        
  1564. Firefox {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
  1565. Thunderbird    {3550f703-e582-4d05-9a08-453d09bdfdc6}
  1566. Nvu {136c295a-4a5a-41cf-bf24-5cee526720d5}
  1567. Mozilla Suite {86c18b42-e466-45a9-ae7a-9b95ba6f5640}
  1568. SeaMonkey {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}
  1569. Sunbird {718e30fb-e89b-41dd-9da7-e25a45638b28}
  1570. Netscape Browser {3db10fab-e461-4c80-8b97-957ad5f8ea47}
  1571. Flock Browser {a463f10c-3994-11da-9945-000d60ca027b}    
  1572. */
  1573.  
  1574. /**
  1575.  * get the  messenger apps    location
  1576.  * first check prefs if already set
  1577.  * 
  1578.  */ 
  1579. function rmFx_MessengerApp(){
  1580. //------------------------------------------------------------------------------
  1581.     var fileValid = true;
  1582.     var mFile = null;
  1583.     var mailApp = "";
  1584.     
  1585.     var mFileServ = Components.classes["@mozilla.org/file/directory_service;1"]                                  
  1586.                        .getService(Components.interfaces.nsIProperties);
  1587.                                
  1588.     var file = Components.classes["@mozilla.org/file/local;1"]
  1589.                       .createInstance(Components.interfaces.nsILocalFile);
  1590.     // sets the default location for messenger app    
  1591.     var appNameX =Components.classes["@mozilla.org/xre/app-info;1"];
  1592.     var appName = appNameX.getService(Components.interfaces.nsIXULAppInfo).name;
  1593.     var appID = appNameX.getService(Components.interfaces.nsIXULAppInfo).ID;
  1594.  
  1595.     var osInfo = rmFx_opSystemInfo();
  1596.    
  1597.     if (rmFx_isMessenger()) {
  1598.         mFile = mFileServ.get("CurProcD", Components.interfaces.nsIFile);
  1599.         
  1600.         if (osInfo.indexOf("WINNT") != -1) {
  1601.             mFile.append(appName + ".exe");                       
  1602.         }
  1603.         if(osInfo.indexOf("Linux") != -1) {
  1604.             mFile.append(appName.toLowerCase());                                  
  1605.         }
  1606.         if(osInfo.indexOf("Darwin") != -1) {
  1607.             var mFile = mFileServ.get("LocApp", Components.interfaces.nsIFile);
  1608.             mFile.append(appName + ".app");                      
  1609.         }
  1610.     }
  1611.  
  1612.     try {
  1613.         var mailApp = reminderFox_prefsBranch.getCharPref(REMINDER_FOX_MAIL_PATH );
  1614.     } catch (ex) {}
  1615.  
  1616.  
  1617.     try { 
  1618.         file.initWithPath(mailApp);
  1619.         fileValid = file.exists();
  1620.     }     catch ( e ) {
  1621.         fileValid = false;
  1622.     }    
  1623.  
  1624.     if ((fileValid == false) && (mFile != null)) {
  1625.         mailApp = mFile.path;
  1626.         file.initWithPath(mailApp);
  1627.         fileValid = true;
  1628.     }
  1629.  
  1630.     if (fileValid == false) { // mailApp / OS not valid, ask user
  1631.     
  1632. //gW appPicker   2009-10-03     +++2do  change for application menu (see FX --> Options --> Applications)
  1633.         
  1634.         var fp = Components.classes["@mozilla.org/filepicker;1"]
  1635.                 .createInstance(Components.interfaces.nsIFilePicker);
  1636.         var winTitle = "Select Mail/Messenger Application" // this._prefsBundle.getString("fpTitleChooseApp");
  1637.         fp.init(window, winTitle, Components.interfaces.nsIFilePicker.modeOpen);
  1638.         fp.appendFilters(Components.interfaces.nsIFilePicker.filterApps);
  1639.      
  1640.         // Prompt the user to pick an app.  If they pick one, and it's a valid
  1641.         // selection, then set it for 'mailto' / 'messenger'
  1642.         
  1643.         if (fp.show() == Components.interfaces.nsIFilePicker.returnOK 
  1644.                 && fp.file && rmFxUtil.isValidHandlerExecutable(fp.file)) 
  1645.         {
  1646.             var handlerApp =rmFxUtil.getLocalHandlerApp(fp.file);
  1647.  
  1648.         } else {          
  1649.             reminderFox_prefsBranch.setCharPref(REMINDER_FOX_MAIL_PATH, "");
  1650.              
  1651.             return "";  // return file object
  1652.         }
  1653.             
  1654.         var mailApp = fp.file.path;
  1655.         reminderFox_prefsBranch.setCharPref(REMINDER_FOX_MAIL_PATH, mailApp); 
  1656.  
  1657.         file.initWithPath(mailApp);
  1658.     }    
  1659.  
  1660.     
  1661.     if(osInfo.indexOf("Darwin") != -1) {
  1662.         
  1663.         if (mailApp.toLowerCase().indexOf("-bin") == -1) {
  1664.             file.initWithPath(mailApp);    
  1665.             
  1666.             file.append("Contents"); 
  1667.             file.append("MacOS");
  1668.             
  1669.             if (mailApp.toLowerCase().indexOf("thunderbird") != -1)  file.append("thunderbird-bin");
  1670.             if (mailApp.toLowerCase().indexOf("seamonkey") != -1)  file.append("seamonkey-bin");
  1671.             if (mailApp.toLowerCase().indexOf("postbox") != -1)  file.append("postbox-bin");
  1672.             fileValid = true;
  1673.         }
  1674.     }
  1675.     
  1676.     reminderFox_prefsBranch.setCharPref(REMINDER_FOX_MAIL_PATH, mailApp); 
  1677.     return file;  // return file object
  1678. }
  1679.  
  1680.  
  1681. // ------------  "Browse" for 'mail app' path -------------------
  1682.  
  1683. function rmFx_mailAppStringBrowse() { 
  1684.     
  1685.     reminderFox_prefsBranch.setCharPref (REMINDER_FOX_MAIL_PATH, ""); 
  1686.     document.getElementById('mailApp.location.input').value = rmFx_MessengerApp().path;
  1687. }    
  1688.  
  1689.  
  1690. // -------------- open 'mail' addressbook ------------------
  1691.  
  1692. function rmFx_abookOpen() {
  1693.     
  1694.     // first enable textbox for easy pasting
  1695.     document.getElementById('attendees').removeAttribute( "disabled");
  1696.     document.getElementById('inviteEnable').setAttribute( "checked","true");
  1697.  
  1698.     const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
  1699.     var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  1700.     var windowManagerInterface = windowManager.QueryInterface(nsIWindowMediator);
  1701.  
  1702.     var inType    =    "mail:addressbook";
  1703.     var topWindow = windowManagerInterface.getMostRecentWindow( inType );
  1704.     
  1705.     if ( topWindow ) {    // if already open bring it to front
  1706.         topWindow.focus();
  1707.     } else {
  1708.         
  1709.         var osInfo = rmFx_opSystemInfo();
  1710.         var mailApp = rmFx_MessengerApp();
  1711.         if ((mailApp == null) || (mailApp == ""))  {
  1712.             rmFxUtil.PromptAlert("Messenger not found!");  // reminderFox_getBundle().getString("rf.schedule. $$string$$ "));
  1713.             return;
  1714.         }
  1715.         try {
  1716.             go4Process.init(mailApp);
  1717.         } catch (ex) {}
  1718.         go4Process.run(false, new Array( "-addressbook"), 1);
  1719.     }
  1720. }
  1721.  
  1722. function rmFx_abookMini() {
  1723.     var    inType    =    "mail:addressbook";
  1724.  
  1725.     const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
  1726.     var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  1727.     var    windowManagerInterface = windowManager.QueryInterface(nsIWindowMediator);
  1728.     var topWindow = windowManagerInterface.getMostRecentWindow( inType );
  1729.  
  1730.     topWindow.minimize();
  1731. }
  1732.  
  1733. function rmFx_insertAttendees(xAttendees) {
  1734. // focus on the  'invitation' window
  1735.     var    inType    =    "window:ItemDialog";
  1736.  
  1737.     const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
  1738.     var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  1739.     var    windowManagerInterface = windowManager.QueryInterface(nsIWindowMediator);
  1740.     var topWindow = windowManagerInterface.getMostRecentWindow( inType );
  1741.  
  1742.     try {
  1743.         topWindow.focus();
  1744.         var attendeeBox = topWindow.document.getElementById("attendees");
  1745.         var attendeeText = attendeeBox.value;
  1746.         var end0 = attendeeBox.selectionEnd; 
  1747.  
  1748.         if (attendeeText == "" && attendeeText != null){
  1749.             attendeeBox.value = xAttendees;
  1750.         }
  1751.         else {
  1752.             if (attendeeText.charAt(attendeeText.length) != ',') {
  1753.                 attendeeBox.value = attendeeText + ',' + xAttendees;
  1754.             } else {
  1755.                 attendeeBox.value = attendeeText + xAttendees;
  1756.             }
  1757.         }
  1758.         var end = attendeeBox.textLength;
  1759.         attendeeBox.setSelectionRange(end);
  1760.         topWindow.focus();
  1761.     } catch (e) {}
  1762. }
  1763.  
  1764. /////////////////////// iCalUtil ///////////////////////////////////////////////
  1765.  
  1766. function iCalUtil () {
  1767. }
  1768.  
  1769.           //    icsString  ORGANIZER;CN=name:MAILTO:mailadr@abc.xx
  1770.           //    returns:   name<mailadr@abc.xx>
  1771.         iCalUtil.getMailAddress = function (icsString) {    
  1772.             var persName="";
  1773.             var persMail="";
  1774.             var fndIndex = icsString.toUpperCase().lastIndexOf( "MAILTO:");  
  1775.             if (fndIndex != -1) {
  1776.                 persMail = icsString.substring( fndIndex + 7);          
  1777.             } else {
  1778.                 var colnIndex = icsString.lastIndexOf(":");
  1779.                 if (colnIndex != -1) {
  1780.                     if (icsString.substring( colnIndex).indexOf("@") != -1) {
  1781.                         persMail = icsString.substring( colnIndex + 1);  }
  1782.                 }   
  1783.             }     
  1784.             var fndIndex = icsString.toUpperCase().indexOf( "CN=" ); 
  1785.             if (fndIndex != -1) {
  1786.                 var fndString = icsString.substring( fndIndex + 3);
  1787.                 var colnIndex = fndString.indexOf(":");
  1788.                 var semkiIndex = fndString.indexOf(";");
  1789.             
  1790.                 if ((semkiIndex != -1) && (semkiIndex < colnIndex))  {
  1791.                     persName = fndString.substring( 0, semkiIndex);       
  1792.                 } else { persName = fndString.substring( 0, colnIndex);  }
  1793.             }
  1794.             
  1795.             if (persName == "") {return '<' + persMail +'>';
  1796.                 } else {
  1797.                 return persName + '<' + persMail +'>';
  1798.             }
  1799.         }
  1800.  
  1801.   
  1802. // http://tools.ietf.org/html/rfc2446#section-3.2.2.1 Rescheduling an Event
  1803. function rmFx_iCalReschedule(originalReminder, currentReminder) {
  1804. // ---------------------------------------------------------------    
  1805.     if (originalReminder.extraInfo == null) return;
  1806.     
  1807.     var extraInfoOrginal = rmFx_extraInfoArray (originalReminder);
  1808.     var extraInfoCurrent = rmFx_extraInfoArray (currentReminder);
  1809.     
  1810.     var currentATT = rmFx_extraInfo( extraInfoOrginal,"ATTENDEE"); 
  1811.     if (currentATT == null || currentATT.length == 0)  { return;}  
  1812.     // OK  it's a Invitation/Schedule .. rescheduling requirements:
  1813.     //         1. is the ORGANIZER one of my accounts?  Maybe hard with FX!!
  1814.     //         2.  A rescheduled event involves time or recurrence intervals 
  1815.     //             and possibly the location or description 
  1816.     
  1817.   // ad 1.  check ORGANIZER
  1818.     // currentORG =   "ORGANIZER;CN=name:MAILTO:mailadr@abc.xx"
  1819.     // myAccounts =   "name<mailadr@xyz.xx>,name2<mailadr2@mmm.zz>"
  1820.  
  1821.     var currentORG = rmFx_extraInfo( extraInfoOrginal,"ORGANIZER", ";");    
  1822.     
  1823.     if (currentORG.length == 0)  { return;}  // no ORGANIZER
  1824.     var fndIndex = currentORG.toUpperCase().lastIndexOf( "MAILTO:" ); 
  1825.  
  1826.     var aa= rmFxMsg.myMailIDs();
  1827.     
  1828.     if (aa.toUpperCase().indexOf(currentORG
  1829. //    if (rmFxMsg.myMailIDs().toUpperCase().indexOf(currentORG
  1830.         .substring( fndIndex + 7).toUpperCase()) == -1 ) {return;} // no ORGANIZER -- no Invitation/Schedule
  1831.       // ORGANIZER ok
  1832.       
  1833.     var fromAddress = iCalUtil.getMailAddress(currentORG);      
  1834.           
  1835.   // ad 2. check if parameters changed     
  1836.  
  1837.     if (currentReminder.endDate == null  && originalReminder.endDate != null) {
  1838.         currentReminder.endDate = originalReminder.endDate;
  1839.     }    
  1840.  
  1841.     var dateChange   = originalReminder.date.toGMTString()
  1842.                      != currentReminder.date.toGMTString()
  1843.                  ||     originalReminder.endDate.toGMTString()
  1844.                      != currentReminder.endDate.toGMTString();
  1845.     var recurChange    = ( 
  1846.               originalReminder.recurrence.byDay      != currentReminder.recurrence.byDay
  1847.         ||    originalReminder.recurrence.endDate  != currentReminder.recurrence.endDate
  1848.         ||    originalReminder.recurrence.interval != currentReminder.recurrence.interval
  1849.         ||    originalReminder.recurrence.type      != currentReminder.recurrence.type);
  1850.  
  1851.     var sumChange    = originalReminder.summary != currentReminder.summary;
  1852.  
  1853.     var locChange    = originalReminder.location != currentReminder.location;
  1854.  
  1855.     if ( !(dateChange || recurChange || sumChange|| locChange ) ) {return;}  // no Change
  1856.  
  1857.   //  ORGANIZER 'rescheduled' the event   
  1858.   //   read ORGANIZER   from reminder and set it to 'fromAddress'    
  1859.   //   read ATTENDEE(s) from reminder and set it to 'attendees'    
  1860.   //   parameter to be updated:
  1861.   //   - DTSTAMP
  1862.   //   - SEQUENCE
  1863.   //   - SUMMARY/DESCRIPTION
  1864.   //   - LASTMODIFIED ????
  1865.     
  1866.     
  1867.     var aExtraInfo  = rmFx_extraInfoArray(currentReminder);
  1868.  
  1869.     // for ATTENDEE(s) have to build the to=mailString and all ATT need to called RSVP!!
  1870.  
  1871.     var attendeeString ="";        // for iCal ATTENDEE:
  1872.     var attendees ="";            // for mail compose to=
  1873.     
  1874.     for (var i=0; i< aExtraInfo.length; i++) {
  1875.         if (aExtraInfo[i].indexOf("ATTENDEE") == 0) {
  1876.  
  1877.             var attendeeName="";
  1878.             var attendeeMail="";
  1879.             var fndIndex = aExtraInfo[i].toUpperCase().lastIndexOf( "MAILTO:");  
  1880.             if (fndIndex != -1) {
  1881.                 attendeeMail = aExtraInfo[i].substring( fndIndex + 7);          
  1882.             } else {
  1883.                 var colnIndex = aExtraInfo[i].lastIndexOf(":");
  1884.                 if (colnIndex != -1) {
  1885.                     if     (aExtraInfo[i].substring( colnIndex).indexOf("@") != -1) {
  1886.                         attendeeMail = aExtraInfo[i].substring( colnIndex + 1);  }
  1887.                 }   
  1888.             }     
  1889.             var fndIndex = aExtraInfo[i].toUpperCase().indexOf( "CN=" ); 
  1890.             if (fndIndex != -1) {
  1891.                 var fndString = aExtraInfo[i].substring( fndIndex + 3);
  1892.                 var colnIndex = fndString.indexOf(":");
  1893.                 var semkiIndex = fndString.indexOf(";");
  1894.                 
  1895.                 if ((semkiIndex != -1) && (semkiIndex < colnIndex))  {
  1896.                     attendeeName = fndString.substring( 0, semkiIndex);       
  1897.                 } else {attendeeName = fndString.substring( 0, colnIndex);  }
  1898.             }
  1899.             if (attendeeName == "") {attendees +=  '<' + attendeeMail +'>,';
  1900.                 } else {
  1901.                 attendees += attendeeName + '<' + attendeeMail +'>,';
  1902.             }
  1903.             
  1904.             var attendeeString ="ATTENDEE";        
  1905.             if (attendeeName != "") {attendeeString += ";CN=" + attendeeName}
  1906.             if (attendeeMail != "") {attendeeString += ";RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:MAILTO:" + attendeeMail}
  1907.             aExtraInfo[i] = attendeeString;
  1908.         }
  1909.     }
  1910.     rmFx_extraInfoReplace (aExtraInfo, "SEQUENCE", rmFx_extraInfo(aExtraInfo, "SEQUENCE")*1 + 1);
  1911.     rmFx_extraInfoReplace (aExtraInfo, "DTSTAMP", rmFx_setDateTimeZ());
  1912.     rmFx_extraInfoReplace (aExtraInfo, "COMMENT", "");        // erase old
  1913.     
  1914.     currentReminder.extraInfo = aExtraInfo.join("\\n");
  1915.     // delete double 'CR'
  1916.     currentReminder.extraInfo = currentReminder.extraInfo.replace(new RegExp(/\\n\\n/g),"\\n");
  1917.  
  1918.     var chText =    (dateChange        ? " '" + reminderFox_getBundle().getString("rf.add.mail.message.datetime") + "' "         : "") // "Date/Time") 
  1919.                     +     (recurChange    ? " '" + reminderFox_getBundle().getString("rf.add.mail.message.reccurance") + "' "     : "") // "Recurrance") 
  1920.                     +    (sumChange         ? " '" + reminderFox_getBundle().getString("rf.schedule.description") + "' "             : "") // "Title") 
  1921.                     +    (locChange        ? " '" + reminderFox_getBundle().getString("rf.mail.ical.send.location") + "' "         : ""); // "Location");
  1922.         
  1923.     var methodTyp = "REQUEST";
  1924.     var newNotes = "[iCal] " + methodTyp + ": " + reminderFox_getBundle().getString("rf.schedule.statusOf")
  1925.         + ": " + reminderFox_parseDateTimes(rmFx_extraInfo(aExtraInfo,"DTSTAMP"))
  1926.         + " [#" + rmFx_extraInfo(aExtraInfo,"SEQUENCE") +"]\n"
  1927.         + "*" + reminderFox_getBundle().getString("rf.schedule.statusChanged")+"*  " + chText +"\n\n";    
  1928.     currentReminder.notes = newNotes + currentReminder.notes
  1929.     var reminders = new Array();
  1930.     reminders[0] = currentReminder;
  1931.     var iCalInvite = true;
  1932.     rmFx_sendEventNow(reminders, "", methodTyp, fromAddress, attendees, iCalInvite); 
  1933. }
  1934.  
  1935. function rmFx_inviteStatus(currentReminder) {
  1936. // --------------------------------------------    
  1937. //    var extraInfoOrginal = rmFx_extraInfoArray (currentReminder);
  1938.  
  1939.     var currentORG = rmFx_extraInfo( rmFx_extraInfoArray (currentReminder),"ORGANIZER");    
  1940.     if (currentORG.length == 0)  { return;}  // no ORGANIZER
  1941.  
  1942.     var fndIndex = currentORG.toUpperCase().lastIndexOf( "MAILTO:" ); 
  1943.     if (rmFxMsg.myMailIDs().toUpperCase()
  1944.         .indexOf(currentORG.substring( fndIndex + 7).toUpperCase()) == -1) {
  1945.         
  1946.             document.getElementById("newReminderText").setAttribute("disabled", "true");    
  1947.             
  1948.             document.getElementById("reminderFox-all-day").setAttribute("disabled", "true");    
  1949.  
  1950.             document.getElementById("reminderFox-timeList").setAttribute("disabled", "true");    
  1951.             document.getElementById("yearlist").setAttribute("disabled", "true");    
  1952.             document.getElementById("monthlist").setAttribute("disabled", "true");    
  1953.             document.getElementById("daylist").setAttribute("disabled", "true");
  1954.             
  1955.             document.getElementById("reminderFox-endTimeList").setAttribute("disabled", "true");    
  1956.             document.getElementById("endyearlist").setAttribute("disabled", "true");    
  1957.             document.getElementById("endmonthlist").setAttribute("disabled", "true");    
  1958.             document.getElementById("enddaylist").setAttribute("disabled", "true");    
  1959.  
  1960.             document.getElementById("datepickerToggle").setAttribute("disabled", "true");
  1961.             document.getElementById("datepickerEndToggle").setAttribute("disabled", "true");
  1962.  
  1963.             document.getElementById("location").setAttribute("disabled", "true");
  1964.             document.getElementById("reminderFox-repeat").setAttribute("disabled", "true");
  1965.     }
  1966. }
  1967.  
  1968. function rmFx_extraInfoReplace (extraInfo, itemName, itemValue) {
  1969. // ------ writes to aExtraInfo array using item 
  1970.     itemName = itemName.toUpperCase();
  1971.     var result="";
  1972.     if (extraInfo != null) {
  1973.         if (extraInfo.length > -1) {
  1974.             for (var n =0; n < extraInfo.length; n++) {    
  1975.                 if (extraInfo[n].indexOf( itemName )  == 0) { 
  1976.                     if  (itemValue == "") {
  1977.                         extraInfo[n] ="";
  1978.                         break;
  1979.                     }                  
  1980.                     extraInfo[n] = itemName + ":" + itemValue;
  1981.                     break
  1982.                 }
  1983.             }
  1984.         }
  1985.     }      
  1986. }
  1987.  
  1988. function rmFx_setDateTimeZ() {    
  1989.     var currentDate = new Date();
  1990.     var tzOffset = new Date().getTimezoneOffset(); 
  1991.     currentDate.setMinutes( currentDate.getMinutes() + tzOffset );                        
  1992.          
  1993.     return  reminderFox_getDateAsString(currentDate)+ "Z";   
  1994. }
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000. /**
  2001. //gWTEST rmFx_iCalTest    TEST  TEST  TEST  TEST  TEST  TEST 
  2002. <br>  test purpose only:  copy a BEGIN:CALENDAR ... END:CALENDAR 
  2003. <br>         to clipboard and call this function to process /simulate
  2004. <br>         an 'iCal import form email'
  2005. */                     
  2006. function rmFx_iCalTest (){
  2007.     var clip = Components.classes["@mozilla.org/widget/clipboard;1"]. 
  2008.     getService(Components.interfaces.nsIClipboard); 
  2009.     if (!clip) return false; 
  2010.     
  2011.     var trans = Components.classes["@mozilla.org/widget/transferable;1"]. 
  2012.         createInstance(Components.interfaces.nsITransferable); 
  2013.     if (!trans) return false; 
  2014.     trans.addDataFlavor("text/unicode");
  2015.  
  2016.     clip.getData(trans,clip.kGlobalClipboard); 
  2017.     var str = new Object(); 
  2018.     var strLength = new Object(); 
  2019.     trans.getTransferData("text/unicode",str,strLength);
  2020.  
  2021.     if (str) str = str.value.QueryInterface(Components.interfaces.nsISupportsString); 
  2022.     if (str) pastetext = str.data.substring(0,strLength.value / 2);
  2023.  
  2024.     var mInvitation = "[iCal] Schedule copied from Clipboard";        
  2025.     this.reminderfox_Method ="CLIPBOARD";
  2026.     
  2027.     rmFx_iCalTagging(rmFxGetiCalFromTextBody(pastetext, mInvitation));       
  2028.     return true;          
  2029. }
  2030.  
  2031.  
  2032. /**
  2033.  *    Change Groupbox elements for 'Export' and 'Send' dialogs
  2034.  *  
  2035.  */
  2036. function rmFx_sendExportChange(mode) {
  2037.     var sendOp;
  2038.         
  2039.     if (mode.id == "exportSection") sendOp = !mode.checked;
  2040.     if (mode.id == "sendSection")   sendOp = mode.checked;
  2041.  
  2042.     // called from ... send Invitation as 'info' see: rmFx_invitationLoadDialog
  2043.     if (mode == "sendSection")      sendOp = true;      
  2044.  
  2045.     if (sendOp) {
  2046.         /* --- 'Export' -->     disabled */ 
  2047.         document.getElementById("exportSection").setAttribute("checked", "false");
  2048.         document.getElementById("exportFile").setAttribute("disabled", "true");        
  2049.         document.getElementById("getFileLocationButton").setAttribute("disabled", "true");        
  2050.  
  2051.         /* --- 'Send' -->       enabled */
  2052.         document.getElementById("sendSection").setAttribute("checked", "true");
  2053.         
  2054.         document.getElementById('mailApp.Description')   .setAttribute( "class", "textNormal" ); 
  2055.         document.getElementById('mailApp.location.input').setAttribute( "class", "textNormal" ); 
  2056.         
  2057.         document.getElementById("organizerMenu").removeAttribute("disabled");         
  2058.         document.getElementById("inviteEnable").removeAttribute("disabled");
  2059.  
  2060.         if (document.getElementById('inviteEnable').checked == true){
  2061.             document.getElementById('reminderFox-attendeeGroup').setAttribute( "hidden", false );            
  2062.             document.getElementById('reminderFox-commentGroup').setAttribute( "hidden", false );
  2063.         }
  2064.         document.getElementById('attendees').removeAttribute( "disabled");
  2065.         document.getElementById('commentText').removeAttribute( "disabled");
  2066.         document.getElementById("mailAppButton").removeAttribute("disabled");
  2067.         
  2068.     //  check the messenger to be used
  2069.         document.getElementById('mailApp.location.input').value = rmFx_MessengerApp().path;
  2070.     
  2071.     } else {
  2072.         /* --- 'Export' -->     enabled */ 
  2073.         document.getElementById("exportSection").setAttribute("checked", "true");
  2074.         document.getElementById("exportFile").removeAttribute("disabled");        
  2075.         document.getElementById("getFileLocationButton").removeAttribute("disabled");        
  2076.          
  2077.         /* --- 'Send' -->       disabled */
  2078.         document.getElementById("sendSection").setAttribute("checked", "false");
  2079.  
  2080.         document.getElementById('mailApp.Description')   .setAttribute( "class", "textDisabled" );            
  2081.         document.getElementById('mailApp.location.input').setAttribute( "class", "textDisabled" );           
  2082.  
  2083.         document.getElementById("organizerMenu").setAttribute("disabled", "true");
  2084.         document.getElementById("inviteEnable").setAttribute("disabled","true");
  2085.  
  2086.         document.getElementById('reminderFox-attendeeGroup').setAttribute( "hidden", true );            
  2087.         document.getElementById('reminderFox-commentGroup').setAttribute( "hidden", true );
  2088.  
  2089.         document.getElementById("mailAppButton").setAttribute("disabled", "true");          
  2090.     }
  2091.     sizeToContent();
  2092. }
  2093.  
  2094. /**
  2095.  *  Set the file for  'export' of reminders/todos
  2096.  *  .. and set prefs for it
  2097.  *  
  2098.  */
  2099. function rmFx_getExportFile () {
  2100.  
  2101.     var currentFileName     = document.getElementById("exportFile").value;
  2102.     var windowText          = reminderFox_getBundle().getString("rf.export.send.title");   // "Set / Select file to export reminder(s)";  
  2103.     var filterName          = "Event File (ICS)";
  2104.     var defaultExtension    = "ICS";
  2105.     var rmFx_exportFile     = "exportEventsFile"    // set as prefs 'extensions.reminderFox.exportEventsFile'
  2106.     
  2107.     var file = rmFx_filePicker (windowText, filterName, defaultExtension, 
  2108.                 currentFileName /*defaultString*/, rmFx_exportFile /*prefsName*/, 1 /*mode = modeSave*/) 
  2109.     
  2110.     if (file != null) {
  2111.         reminderFox_prefsBranch.setCharPref(rmFx_exportFile, file.path);
  2112.         document.getElementById("exportFile").setAttribute("value", file.path);
  2113.     }
  2114. }